Surface that passes through points defined on grid

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
snow54
Posts: 17
Joined: Sat Apr 24, 2021 8:42 am
Location: Japan

Surface that passes through points defined on grid

Post by snow54 »

Is there a way to make a surface that passes through all the points defined on a grid? Also, the edges should match the given curves.

I tried to accomplish this by "surface filling" but it results in a surface that has some distance from the given points as shown in a simple example below. Also, since I have roughly 100x100 points in the actual problem, "surface filling" takes very long time.
Screenshot from 2022-07-01 23-03-20.png
Screenshot from 2022-07-01 23-03-20.png (112.91 KiB) Viewed 1360 times

Code: Select all

import FreeCAD as App
import Draft
import numpy as np

doc = App.newDocument()

L=16
a = App.Vector(-L, -L, 0)
b = App.Vector(-L, L, 0)
c = App.Vector(L, L, 0)
d = App.Vector(L, -L, 0)

obj1=Draft.make_line(a,b)
obj2=Draft.make_line(b,c)
obj3=Draft.make_line(c,d)
obj4=Draft.make_line(d,a)
surf = doc.addObject("Surface::Filling", "Surface")
surf.BoundaryEdges = [(obj1, "Edge1"),
                      (obj2, "Edge1"),
                      (obj3, "Edge1"),
                      (obj4, "Edge1")]
doc.recompute()

n=11
x=np.linspace(-L+L/(n-1),L-L/(n-1),n)
y=np.linspace(-L+L/(n-1),L-L/(n-1),n)
X, Y =np.meshgrid(x,y)
p=[]
pv=[]
rng = np.random.default_rng(1)
a=rng.random(X.shape)
for k in np.arange(X.shape[0]):
    for kk in np.arange(X.shape[1]):
        p.append(Draft.make_point(App.Vector(X[k,kk],Y[k,kk], (1-0.5*a[k,kk])*10*np.sin(X[k,kk]/L*np.pi)*np.cos(0.5*Y[k,kk]/L*np.pi))))
        pv.append((p[-1],"Vertex1"))

surf.Points=pv
doc.recompute()

Part.BSplineSurface() seems to be able to create a surface in a similar way according to the posts below, but it still has some distance from the points.
https://forum.freecadweb.org/viewtopic.php?t=16473
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Surface that passes through points defined on grid

Post by onekk »

Try searching in Curves wb thread.

or search post from chrisb or Chris_G niw I'm on mobile and I could not do proper search.

There should be an example, the problem could be limiting the boundaries of the surface.

try to search "bspline boundary" and see what is returned.

Hope it helps.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
User avatar
Chris_G
Veteran
Posts: 2579
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: Surface that passes through points defined on grid

Post by Chris_G »

Code: Select all

bs = Part.BSplineSurface()
# array_of_points is a 2D array : [row1, row2, row3]
bs.interpolate(array_of_points)
obj = Part.show(bs.toShape(), "interpolation surface")
snow54
Posts: 17
Joined: Sat Apr 24, 2021 8:42 am
Location: Japan

Re: Surface that passes through points defined on grid

Post by snow54 »

Thank you onekk and Chris_G for your quick replies.

I tried the script by Chris_G, which gave me the geometry shown below. It has a significant overshoot and also the edges of the surface obviously do not match the given ones. Is there a way to create a surface with less overshoot and the edges matched with the given ones? I need to combine the surface with another surface, so the edges must exactly match the given ones.

I'm also searching on Curve wb thread but have not been able to find the information I need so far.
Screenshot from 2022-07-02 09-38-33.png
Screenshot from 2022-07-02 09-38-33.png (63.1 KiB) Viewed 1271 times
snow54
Posts: 17
Joined: Sat Apr 24, 2021 8:42 am
Location: Japan

Re: Surface that passes through points defined on grid

Post by snow54 »

I think I found what onekk was trying to direct me to.
https://forum.freecadweb.org/viewtopic.php?f=36&t=63949

However, the mention below is an issue for me. It would be great if there is a way to constrain the surface on given curves.
Chris_G wrote: Wed Nov 24, 2021 10:15 pm
Devy wrote: Wed Nov 24, 2021 1:07 am I also am curious to see how adjacent surfaces could blend into other surfaces made with the techniques you outlined here. For example, the scanned data this point cloud comes from has fillets that should connect to some boundaries of the surface made here.
When the goal is to get a good watertight model, then you can only use this technique for the main starting surface, but the other surfaces that connect it must use more precise algorithms.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Surface that passes through points defined on grid

Post by onekk »

It is bit easy to work with points cloud as the name is telling they are simply points.

This is the core of all the math work approximation!

Someone as said that "the exact science" (mathematics) is dominated by the concept of approximation.

Take limits, integrals and many other concepts that will be true "for an epsilon".

Here the problem is to obtain curves at boundaries that could be used to create joining surfaces.

But if you have created a surface using interpolation on a point cloud, you have no "curves" at all as starting data, so the problem is always the same:

What are you trying to achieve?

What are the "given curves", maybe "boundary lines"?

Side note use

Code: Select all

Part.LineSegment
and not Draft things if you want to operate with Part WB.

Regards

Carlo D.
Last edited by onekk on Sun Jul 03, 2022 10:13 am, edited 1 time in total.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
snow54
Posts: 17
Joined: Sat Apr 24, 2021 8:42 am
Location: Japan

Re: Surface that passes through points defined on grid

Post by snow54 »

onekk wrote: Sat Jul 02, 2022 8:34 am What are you trying to achieve?
Here is what I would like to achieve.
  1. I have input variables as given in the attachment.
    • X: x coordinates of rectangular mesh
    • Y: y coordinates of rectangular mesh
    • T: Thickness at corresponding (x, y)
    • Z: z coordinates of camber (midpoint between upper and lower surfaces) at corresponding (x, y)
    • xb: x coordinates of the boundary curve
    • yb: y coordinates of the boundary curve
  2. Create an upper surface with z=Z+T/2 and a lower surface with z=Z-T/2. The upper and lower surfaces shall match at the boundary curve and they shall be trimmed there. z coordinates of the boundary curve shall be an interpolation of Z values at neighboring points. T and Z are defined outside of the boundary but they can be ignored.
  3. Create a solid enclosed by the upper and lower surfaces. It is used to create a model for CFD (computational fluid dynamics) analysis.
In the past, I defined crosssections using BSpline perpendicular to y axis and used "loft" to connect the crosssections to create a solid. However, this method provides a skewed geometry when the crosssections change significantly, so I wanted to use a better different method.
onekk wrote: Sat Jul 02, 2022 8:34 am Side note use

Code: Select all

Part.LineSegment

and not Draft things if you want to operate with Part WB.
Thank you for the advice. I'm still learning FreeCAD. I found your FreeCAD scripting guide, and I'm starting to read it.
Attachments
inputvars.zip
(190.9 KiB) Downloaded 12 times
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Surface that passes through points defined on grid

Post by onekk »

snow54 wrote: Sun Jul 03, 2022 7:24 am In the past, I defined crosssections using BSpline perpendicular to y axis and used "loft" to connect the crosssections to create a solid. However, this method provides a skewed geometry when the crosssections change significantly, so I wanted to use a better different method.
Loft is somewhat difficult to use, but this example maybe will help you tune the things.

Code: Select all

solid = Part.makeLoft((base, circle), True, False, False, 5)
You could have some more infos about it using:

Code: Select all

help(Part.makeLoft)
makeLoft(list of wires,[solid=False,ruled=False,closed=False,maxDegree=5]) -- Create a loft shape.
So you could tune it on some extent see maybe:

https://wiki.freecadweb.org/Part_Loft_Technical_Details

But you could even use:

Code: Select all

Part.BRepOffsetAPI.MakePipeShell
That has more control on many parts of the operation, sadly there is not yet more documentation around you have to refer to some code found using (makePipeShell) in the search bar of the forum.

It has the ability to define profiles along a Path, so you could define something similar o a "Loft operation", and do many more things.

It is somewhat complex, so probably some help will be usefult to obtain desired results.

I think that if you put together some example code, someone probably could help you to make something useful, in the past when I have asked I have ad some answers, see maybe, although totally unrelated to your problem:

https://forum.freecadweb.org/viewtopic.php?f=22&t=65467

https://forum.freecadweb.org/viewtopic.php?f=22&t=65875

This answer to one of my post, maybe could be useful to your problem.

https://forum.freecadweb.org/viewtopic. ... 99#p519499

And probably this thread:

https://forum.freecadweb.org/viewtopic.php?f=22&t=29027


Side note: You will have some hints, on what persons have most knowledge on this genre of things, you will surely note that some people "names" are recurring in this posts. :D

Hope it helps

Carlo D.

Edit: added some more links
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
snow54
Posts: 17
Joined: Sat Apr 24, 2021 8:42 am
Location: Japan

Re: Surface that passes through points defined on grid

Post by snow54 »

Thanks, Carlo for your information. I'm reading your suggestions but it's a lot of information. I'll get back here once I understand them.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Surface that passes through points defined on grid

Post by onekk »

snow54 wrote: Sun Jul 03, 2022 2:14 pm Thanks, Carlo for your information. I'm reading your suggestions but it's a lot of information. I'll get back here once I understand them.
You are trying to make operations, on some peculiar things, that seems to be "simple" but probably in term of mathematics involved are not so "simple".

Take also in account that the way a 2D surface is described (by FC) follow a way that is slightly different from other softwares and conventions. In one of my excursions someone has told me what convention it follows, but sadly I haven't noted down the informations, but could be also that I'm making a mess with BSpline Curve.

In "Curves WB" forum thread there are some hints, but it is a 129 page long thread, so it is difficult to read all the thread an find relevant informations, maybe "Gordon Surfaces" could reveal some interesting infos, but I'm using my memory that is not very reliable.

I have done some experiments, and the critical point is joining the boundaries of the surfaces to obtain a solid, the difficult is that to have a correct Loft youe "limiting profiles" has to have same number of segments, to avoid artifacts, and similar "order of drawing" (clockwise or counterclockwise), if not the Loft is done with artifacts, or worse crossing the joining surfaces.

Obviously with surfaces obtained using "point cloud" this is hardly the case, so some "curing" has to be applied to the obtained surfaces.

Similar thing, if you want to obtain simply the "side surface" between two surfaces that are not touching, you could use a "ruledsurface" but again it it better to have a similar number of segments, and this is predictable with a polyline or surfaces made by arcs where you could even split an arc in pieces to match number of segments in the two "curves", it is not everytime feasible with BSplines.

I have had some problems and I gave up as I could not create a shell to pass to a "Part.Solid" to make a solid using the BREP paradigm.

Probably there is a way, maybe using some tricks, and as you are interpolating a surface, probably exactness is not a strict requirement.

But I if you put together some code that will help to have a base to work on I'm quite sure that some people could help you to go in the right direction.


At least the code that will create the "two surfaces" to joint and create a solid "between them" will be a start.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Post Reply