Skip to content

Commit 8699a36

Browse files
author
Andrea Mola
committed
further modifications to cad version of ffd.py
1 parent fa6ffae commit 8699a36

File tree

2 files changed

+492
-481
lines changed

2 files changed

+492
-481
lines changed

pygem/cad/ffd.py

Lines changed: 125 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -132,208 +132,219 @@ def __call__(self, obj, dst=None):
132132

133133

134134
# cycle on the faces to get the control points
135-
# init some quantities
136-
faceCount = 0
137-
face_list = []
135+
136+
# iterator to faces (TopoDS_Shape) contained in the shape
138137
faces_explorer = TopExp_Explorer(shape, TopAbs_FACE)
139138

140139
while faces_explorer.More():
141140
# performing some conversions to get the right
142141
# format (BSplineSurface)
142+
143+
# TopoDS_Face obtained from iterator
143144
face = topods_Face(faces_explorer.Current())
144-
nurbs_converter = BRepBuilderAPI_NurbsConvert(face)
145-
nurbs_face = nurbs_converter.Shape()
146-
face_aux = topods_Face(nurbs_face)
147-
brep_face = BRep_Tool.Surface(topods_Face(nurbs_face))
148-
bounds = 0.0
149-
bounds = brep_face.Bounds()
150-
151-
bspline_face = geomconvert_SurfaceToBSplineSurface(brep_face)
152-
# we will then add an amount of nodes that will grant
153-
# us our prescribed resolution both along u and v
145+
# TopoDS_Face converted to Nurbs
146+
nurbs_face = topods_Face(BRepBuilderAPI_NurbsConvert(face).Shape())
147+
# GeomSurface obtained from Nurbs face
148+
surface = BRep_Tool.Surface(nurbs_face)
149+
150+
# surface is now further converted to a bspline surface
151+
bspline_surface = geomconvert_SurfaceToBSplineSurface(surface)
152+
# bounds (in surface parametric space) of the surface
153+
bounds = surface.Bounds()
154+
155+
# we will then add the prescribed amount of nodes
156+
# both along u and v parametric directions
154157
for i in range(self.uKnotsToAdd):
155-
bspline_face.InsertUKnot(bounds[0]+ \
158+
bspline_surface.InsertUKnot(bounds[0]+ \
156159
i*(bounds[1]-bounds[0])/self.uKnotsToAdd, 1, self.tolerance)
157160
for i in range(self.vKnotsToAdd):
158-
bspline_face.InsertVKnot(bounds[2]+ \
161+
bspline_surface.InsertVKnot(bounds[2]+ \
159162
i*(bounds[3]-bounds[2])/self.vKnotsToAdd, 1, self.tolerance)
160163

161-
# openCascade object
162-
occ_face = bspline_face
163164

164165
# extract the Control Points of each face
165-
n_poles_u = occ_face.NbUPoles()
166-
n_poles_v = occ_face.NbVPoles()
167-
control_polygon_coordinates = np.zeros(\
168-
shape=(n_poles_u * n_poles_v, 3))
166+
167+
# number of poles in u direction
168+
n_poles_u = bspline_surface.NbUPoles()
169+
# number of poles in v direction
170+
n_poles_v = bspline_surface.NbVPoles()
171+
# array which will contain the coordinates of the poles
172+
poles_coordinates = np.zeros(shape=(n_poles_u * n_poles_v, 3))
169173
# cycle over the poles to get their coordinates
170174
i = 0
171175
for pole_u_direction in range(n_poles_u):
172176
for pole_v_direction in range(n_poles_v):
173-
control_point_coordinates = occ_face.Pole(\
174-
pole_u_direction + 1, pole_v_direction + 1)
175-
control_polygon_coordinates[i, :] = \
176-
[control_point_coordinates.X(),\
177-
control_point_coordinates.Y(),\
178-
control_point_coordinates.Z()]
177+
# gp_Pnt containing the current pole
178+
pole = bspline_surface.Pole(pole_u_direction + 1,
179+
pole_v_direction + 1)
180+
poles_coordinates[i, :] = [pole.X(), pole.Y(), pole.Z()]
179181
i += 1
180182

181-
## SURFACES PHASE ###############################################
182-
src_pts = control_polygon_coordinates
183-
new_pts = super().__call__(src_pts) # dont touch this line
183+
# the new poles positions are computed through FFD
184+
new_pts = super().__call__(poles_coordinates)
184185

186+
# the surface is now looped again to
187+
# set the new poles positions
185188
i = 0
186189
for pole_u_direction in range(n_poles_u):
187190
for pole_v_direction in range(n_poles_v):
188-
control_point = gp_Pnt(new_pts[i, 0],
189-
new_pts[i, 1],
190-
new_pts[i, 2])
191-
occ_face.SetPole(pole_u_direction + 1,
192-
pole_v_direction + 1,
193-
control_point)
191+
new_pole = gp_Pnt(new_pts[i, 0],
192+
new_pts[i, 1],
193+
new_pts[i, 2])
194+
bspline_surface.SetPole(pole_u_direction + 1,
195+
pole_v_direction + 1,
196+
new_pole)
194197
i += 1
195198
# through moving the control points, we now changed the SURFACE
196-
# of the FACE we are processing we now need to obtain the curves
199+
# underlying FACE we are processing. we now need to obtain the curves
197200
# (actually, the WIRES) that define the bounds of the surface and
198-
# TRIM the surface with them, to obtain the new face
201+
# TRIM the surface with them, to obtain the new FACE
199202

200203
# we start creating a face with the modified surface. we will
201204
#later cut this new face with all the wires that the original
202205
# face had this tolerance can be moved among the function
203206
# parameters
204-
brep = BRepBuilderAPI_MakeFace(occ_face, self.tolerance).Face()
207+
untrimmed_face = BRepBuilderAPI_MakeFace(bspline_surface,
208+
self.tolerance).Face()
205209

206210

207-
# we here start looping on the wires of the original face
208-
# in this first loop we do nothing but count the wires in this
209-
# face few faces have more than one wire: if they have, it is
210-
# because they have holes, and if this is the case one wire
211-
# is the outer, and the others are the inner ones.
212-
# the loop will also tell us which wire is the outer one
213-
wire_count = 0
214-
wire_explorer = TopExp_Explorer(face_aux, TopAbs_WIRE)
215-
while wire_explorer.More():
216-
wire = topods_Wire(wire_explorer.Current())
217-
if wire == breptools_OuterWire(face_aux):
218-
print("Wire", wire_count+1, "is outer wire")
219-
wire_count += 1
220-
wire_explorer.Next()
221-
222211
#we now start really looping on the wires
223212
#we will create a single curve joining all the edges in the wire
224213
# the curve must be a bspline curve so we need to make conversions
225214
# through all the way
226-
wire_count = 0
215+
216+
# list that will contain the (single) outer wire of the face
227217
outer_wires = []
218+
# list that will contain all the inner wires (holes) of the face
228219
inner_wires = []
229-
brep_face = BRep_Tool.Surface(brep)
230-
wire_explorer = TopExp_Explorer(face_aux, TopAbs_WIRE)
220+
# iterator to loop over TopoDS_Wire in the original (undeformed)
221+
# nurbs_face
222+
wire_explorer = TopExp_Explorer(nurbs_face, TopAbs_WIRE)
231223
while wire_explorer.More():
224+
# wire obtained from the iterator
232225
wire = topods_Wire(wire_explorer.Current())
233-
h_bspline_edge = GeomConvert_CompCurveToBSplineCurve()
226+
227+
# joining all the wire edges in a single curve here
228+
# composite curve builder (can only join Bspline curves)
229+
composite_curve_builder = GeomConvert_CompCurveToBSplineCurve()
230+
# iterator to edges in the TopoDS_Wire
234231
edge_explorer = TopExp_Explorer(wire, TopAbs_EDGE)
235-
edgesCount = 0
236232
while edge_explorer.More():
237-
# performing some conversions to get the right format
238-
# (BSplineSurface)
233+
# getting the edge from the iterator
239234
edge = topods_Edge(edge_explorer.Current())
235+
# edge can be joined only if it is not degenerated (zero
236+
# length)
240237
if not BRep_Tool.Degenerated(edge):
241-
bspline_converter = BRepBuilderAPI_NurbsConvert(edge)
242-
bspline_converter.Perform(edge)
243-
bspline_tshape_edge = bspline_converter.Shape()
244-
h_geom_edge, a, b = \
245-
BRep_Tool_Curve(topods_Edge(bspline_tshape_edge))
246-
this_bspline_edge = \
247-
geomconvert_CurveToBSplineCurve(h_geom_edge)
248-
bspline_geom_edge = this_bspline_edge
249-
h_bspline_edge.Add(this_bspline_edge, self.tolerance)
250-
edgesCount += 1
238+
# the edge must be converted to Nurbs edge
239+
# the Nurbs edge converter class
240+
nurbs_converter = BRepBuilderAPI_NurbsConvert(edge)
241+
nurbs_converter.Perform(edge)
242+
# the Nurbs edge
243+
nurbs_edge = topods_Edge(nurbs_converter.Shape())
244+
# here we extract the underlying curve from the Nurbs
245+
# edge
246+
nurbs_curve, a, b = BRep_Tool_Curve(nurbs_edge)
247+
# we convert the Nurbs curve to Bspline curve
248+
bspline_curve = \
249+
geomconvert_CurveToBSplineCurve(nurbs_curve)
250+
# we can now add the Bspline curve to
251+
# the composite wire curve
252+
composite_curve_builder.Add(bspline_curve,
253+
self.tolerance)
251254

252255
edge_explorer.Next()
256+
# GeomCurve obtained by the builder after edges are joined
257+
composite_curve = composite_curve_builder.BSplineCurve()
253258

254-
bspline_geom_hedge = h_bspline_edge.BSplineCurve()
255-
bspline_geom_edge = bspline_geom_hedge
256259

257-
# number of knots is enriched here: this can become a user
258-
# prescribed parameter for the class
259-
firstParam = bspline_geom_edge.FirstParameter()
260-
lastParam = bspline_geom_edge.LastParameter()
260+
# number of knots is enriched here, if required, to
261+
# enhance precision
262+
# start parameter of composite curve
263+
firstParam = composite_curve.FirstParameter()
264+
# end parameter of composite curve
265+
lastParam = composite_curve.LastParameter()
261266
for i in range(self.knotsToAdd):
262-
bspline_geom_edge.InsertKnot(firstParam+ \
267+
composite_curve.InsertKnot(firstParam+ \
263268
i*(lastParam-firstParam)/self.knotsToAdd, 1, \
264269
self.tolerance)
265-
shapesList = TopTools_ListOfShape()
266-
# openCascade object
267-
occ_edge = bspline_geom_edge
268270

269271
# extract the Control Points of each face
270-
n_poles = occ_edge.NbPoles()
271-
control_polygon_coordinates = np.zeros(\
272-
shape=(n_poles, 3))
273-
# cycle over the poles to get their coordinates. The idea here
274-
# is to move poles coordinates to deform the curves
272+
# poles number
273+
n_poles = composite_curve.NbPoles()
274+
# array containing the poles coordinates
275+
poles_coordinates = np.zeros(shape=(n_poles, 3))
276+
# cycle over the poles to get their coordinates
275277
i = 0
276-
for pole in range(n_poles):
277-
control_point_coordinates = occ_edge.Pole(pole + 1)
278-
control_polygon_coordinates[i, :] = \
279-
[control_point_coordinates.X(), \
280-
control_point_coordinates.Y(), \
281-
control_point_coordinates.Z()]
278+
for p in range(n_poles):
279+
# gp_Pnt corresponding to the pole
280+
pole = composite_curve.Pole(p + 1)
281+
# coordinates are added to array
282+
poles_coordinates[i, :] = [pole.X(), pole.Y(), pole.Z()]
282283
i += 1
283284

284-
## CURVES PHASE ############################################
285-
src_pts = control_polygon_coordinates
286-
new_pts = super().__call__(src_pts) # dont touch this line
287-
# save here the `new_pts` into the shape
288-
## END CURVES ##############################################
285+
# the new poles positions are computed through FFD
286+
new_pts = super().__call__(poles_coordinates)
289287

288+
# the Bspline curve is now looped again to
289+
# set the poles positions to new_points
290290
i = 0
291291
for pole in range(n_poles):
292+
# gp_Point corresponding to the new pole coordinates
292293
control_point = gp_Pnt(new_pts[i, 0],
293294
new_pts[i, 1],
294295
new_pts[i, 2])
295-
occ_edge.SetPole(pole + 1, control_point)
296+
composite_curve.SetPole(pole + 1, control_point)
296297
i += 1
298+
# the GeomCurve corresponding to the whole edge has now
299+
# been deformed. Now we must make it become an proper
300+
# wire
301+
302+
# list of shapes (needed by the wire generator)
303+
shapesList = TopTools_ListOfShape()
297304

298-
modified_edge = BRepBuilderAPI_MakeEdge(occ_edge).Edge()
299-
shapesList.Append(modified_edge)
305+
# edge (to be converted to wire) obtained from the modified
306+
# Bspline curve
307+
modified_composite_edge = \
308+
BRepBuilderAPI_MakeEdge(composite_curve).Edge()
309+
# modified edge is added to shapeList
310+
shapesList.Append(modified_composite_edge)
300311

312+
# wire builder
301313
wire_maker = BRepBuilderAPI_MakeWire()
302314
wire_maker.Add(shapesList)
303-
result_wire = wire_maker.Wire()
315+
# deformed wire is finally obtained
316+
modified_wire = wire_maker.Wire()
304317

305318
# now, the wire can be outer or inner. we store the outer
306319
# and (possible) inner ones in different lists
307320
# this is because we first need to trim the surface
308321
# using the outer wire, and then we can trim it
309-
# with the wires corresponding to all the holes. if this
310-
# is not done, the procedure will not work
311-
if wire == breptools_OuterWire(face_aux):
312-
outer_wires.append(result_wire)
322+
# with the wires corresponding to all the holes.
323+
# the wire order is important, in the trimming process
324+
if wire == breptools_OuterWire(nurbs_face):
325+
outer_wires.append(modified_wire)
313326
else:
314-
inner_wires.append(result_wire)
315-
wire_count += 1
327+
inner_wires.append(modified_wire)
316328
wire_explorer.Next()
317329

318330

319331
# so once we finished looping on all the wires to modify them,
320-
# we use the only outer one to trim the surface
321-
face_maker = BRepBuilderAPI_MakeFace(occ_face, outer_wires[0])
332+
# we first use the only outer one to trim the surface
333+
# face builder object
334+
face_maker = BRepBuilderAPI_MakeFace(bspline_surface, outer_wires[0])
322335

323336
# and then add all other inner wires for the holes
324337
for inner_wire in inner_wires:
325338
face_maker.Add(inner_wire)
326339

327340

328341
# finally, we get our trimmed face with all its holes
329-
brep_surf = face_maker.Face()
330-
342+
trimmed_modified_face = face_maker.Face()
331343

332-
compound_builder.Add(compound, brep_surf)
333-
face_list.append(brep_surf)
344+
# trimmed_modified_face is added to the modified faces compound
345+
compound_builder.Add(compound, trimmed_modified_face)
334346

335347
# and move to the next face
336-
faceCount += 1
337348
faces_explorer.Next()
338349

339350

0 commit comments

Comments
 (0)