Here is an example:
Code: Select all
#!/usr/bin/env python3
import math
from OCC.Core import gp
from OCC.Core import TColgp
from OCC.Core import GeomAPI
from OCC.Core import GeomFill
from OCC.Core import BRepTools
from OCC.Core import BRepBuilderAPI
from OCC.Display.SimpleGui import init_display
NO_X = 10
NO_Z = 10
X = 1
Y = 0.1
Z = 2
def ellipse(x, a, b):
"""Calculate the y-coordinate of an ellipse with the one apex at (0,0) and one at (2a,0)."""
return b/a * math.sqrt(a**2 - (x-a)**2)
def parabola(x, a, b):
"""Calculate the y-coordinate of an parabola through the points (0,0), (a,b) and (2a,0)."""
return b * (1 - ((x-a)/a)**2)
def points():
"""Generate the points of our surface."""
array = TColgp.TColgp_Array2OfPnt(1, 2*NO_X-1, 1, NO_Z)
for j in range(NO_Z):
z = (j+10)/NO_Z * Z
b = Z/10 - 0.02*z
# First side (back)
for i in range(1, NO_X):
x = i/NO_X * X
y = parabola(x, X/2, 2*b) + ellipse(x, X/2, b)
point = gp.gp_Pnt(x, y, z)
array.SetValue(i, j+1, point)
# Second side (face)
k = i
for i in range(NO_X, 0, -1):
x = i/NO_X * X
y = parabola(x, X/2, 2*b) - ellipse(x, X/2, b)
point = gp.gp_Pnt(x, y, z)
k += 1
array.SetValue(k, j+1, point)
return array
# Fit a surface to our points
pts = points()
surface = GeomAPI.GeomAPI_PointsToBSplineSurface()
surface.Interpolate(pts, False)
surface = surface.Surface()
# Boundary lines to our surface
u_back, u_face, v_bottom, v_top = surface.Bounds()
bl_back = surface.UIso(u_back)
bl_face = surface.UIso(u_face)
bl_bottom = surface.VIso(v_bottom)
bl_top = surface.VIso(v_top)
# Fit a surface to the open aft end of our surface
surface_aft = GeomFill.geomfill_Surface(bl_back, bl_face)
# Boundary lines to the aft surface
u_bottom2, u_top2, v_face2, v_back2 = surface_aft.Bounds()
bl_bottom2 = surface_aft.UIso(u_bottom2)
bl_top2 = surface_aft.UIso(u_top2)
# Fit a surface to the open bottom of our surface
l_bottom = surface_aft.UIso(u_bottom2)
surface_bottom = GeomFill.geomfill_Surface(bl_bottom, bl_bottom2)
# Fit a surface to the open top of our surface
surface_top = GeomFill.geomfill_Surface(bl_top, bl_top2)
# Display the surfaces
display, start_display, _, _ = init_display()
display.DisplayShape(surface, update=True)
display.DisplayShape(surface_aft, update=True)
display.DisplayShape(surface_bottom, update=True)
display.DisplayShape(surface_top, update=True)
display.FitAll()
start_display()
The surfaces generated are:
- Screenshot from 2021-08-01 18-06-47.png (45.57 KiB) Viewed 2270 times
As can be seen, the bottom and top surfaces ‘overlap’. This is due to the using the whole bottom and the line, which closes the it at the end, when generating the bottom surface with `GeomFill.geomfill_Surface(bl_bottom, bl_bottom2)`. The same at the top.
This approach should work, if I split the bottom section in two at the forward extrema and using these two lines to make a filled surface. NB: This extrema is generally
not at u=1/2!
How do I close the bottom and top ‘gaps’?
Any hint (FreeCAD, C++, PythonOCC, …) is welcome!
Please also note, that the two surfaces in the example are located in a plane. Generally they are
not located in a plane!