4747import os
4848import numpy as np
4949from scipy import special
50- from OCC .Core .TopoDS import TopoDS_Shape , TopoDS_Compound
51-
50+ from OCC .TopoDS import TopoDS_Shape , topods_Compound , TopoDS_Compound , topods_Face , TopoDS_Face , topods_Wire , TopoDS_Wire , topods_Edge , TopoDS_Edge
51+ from OCC .BRep import (BRep_Builder )
52+ from OCC .TopExp import TopExp_Explorer
53+ from OCC .TopAbs import TopAbs_VERTEX , TopAbs_EDGE , TopAbs_FACE , TopAbs_WIRE
54+ from OCC .TopTools import TopTools_ListOfShape
55+ from OCC .BRepBuilderAPI import BRepBuilderAPI_MakeFace , BRepBuilderAPI_MakeWire , BRepBuilderAPI_MakeEdge , BRepBuilderAPI_MakeVertex , BRepBuilderAPI_NurbsConvert
56+ from OCC .BRep import BRep_Tool , BRep_Tool_Curve
57+ from OCC .GeomConvert import geomconvert_SurfaceToBSplineSurface , geomconvert_CurveToBSplineCurve , GeomConvert_CompCurveToBSplineCurve
58+ from OCC .gp import gp_Pnt
59+ from OCC .BRepTools import breptools_OuterWire
60+
61+
62+ from OCC .IGESControl import IGESControl_Reader , IGESControl_Writer
63+
64+
5265from pygem import FFD as OriginalFFD
66+ from pygem .cad .igeshandler import IgesHandler
5367
5468class FFD (OriginalFFD ):
5569 """
@@ -89,14 +103,15 @@ class FFD(OriginalFFD):
89103 >>> new = free_form.modified_mesh_points
90104 """
91105
92- def __call__ (self , obj ):
106+ def __call__ (self , obj , dst = None ):
93107 """
94108 This method performs the deformation on the CAD file.
95109 """
96110
97111 # Manage input
98112 if isinstance (obj , str ): # if a input filename is passed
99- shape = # extract topo_shape from filename
113+ iges_handler = IgesHandler ()
114+ shape = iges_handler .load_shape_from_file (obj )
100115 elif isinstance (obj , TopoDS_Shape ):
101116 shape = obj
102117 # Maybe do we need to handle also Compound?
@@ -105,31 +120,35 @@ def __call__(self, obj):
105120
106121 print ("Modifying faces" )
107122
123+
124+ tol = 1e-5
125+
126+ #create compound to store modified faces
108127 compound_builder = BRep_Builder ()
109- compound = OCC . TopoDS . TopoDS_Compound ()
128+ compound = TopoDS_Compound ()
110129 compound_builder .MakeCompound (compound )
111130
131+
112132 # cycle on the faces to get the control points
113133 # init some quantities
114134 faceCount = 0
115135 face_list = []
116136 control_point_position = [0 ]
117- faces_explorer = TopExp_Explorer (color , TopAbs_FACE )
137+ faces_explorer = TopExp_Explorer (shape , TopAbs_FACE )
118138 mesh_points = np .zeros (shape = (0 , 3 ))
119139
120140 while faces_explorer .More ():
121141 points_orig = []
122142 points_def = []
123143 # performing some conversions to get the right format (BSplineSurface)
124144 print ("Processing face " ,faceCount )
125- face = OCC . TopoDS . topods_Face (faces_explorer .Current ())
145+ face = topods_Face (faces_explorer .Current ())
126146 nurbs_converter = BRepBuilderAPI_NurbsConvert (face )
127147 nurbs_converter .Perform (face )
128148 nurbs_face = nurbs_converter .Shape ()
129- face_aux = OCC .TopoDS .topods_Face (nurbs_face )
130- int_tools = IntTools_FClass2d (face_aux , 1e-3 )
131- brep_face = BRep_Tool .Surface (OCC .TopoDS .topods_Face (nurbs_face ))
132- old_brep_face = BRep_Tool .Surface (OCC .TopoDS .topods_Face (nurbs_face ))
149+ face_aux = topods_Face (nurbs_face )
150+ brep_face = BRep_Tool .Surface (topods_Face (nurbs_face ))
151+ old_brep_face = BRep_Tool .Surface (topods_Face (nurbs_face ))
133152
134153 bounds = 0.0
135154 bounds = brep_face .GetObject ().Bounds ()
@@ -156,14 +175,13 @@ def __call__(self, obj):
156175 v_min = bounds [2 ]
157176 v_max = bounds [3 ]
158177 center = occ_face .Value ((u_min + u_max )/ 2.0 ,(v_min + v_max )/ 2.0 )
159- print ("* Center: " ,center .X (),center .Y (),center .Z ())
178+ print ("Face Center: " ,center .X (),center .Y (),center .Z ())
160179
161180 # extract the Control Points of each face
162181 n_poles_u = occ_face .NbUPoles ()
163182 n_poles_v = occ_face .NbVPoles ()
164183 control_polygon_coordinates = np .zeros (\
165184 shape = (n_poles_u * n_poles_v , 3 ))
166- #print("Number of poles: ", n_poles_u * n_poles_v)
167185 # cycle over the poles to get their coordinates
168186 i = 0
169187 for pole_u_direction in range (n_poles_u ):
@@ -173,76 +191,67 @@ def __call__(self, obj):
173191 control_polygon_coordinates [i , :] = [control_point_coordinates .X (),\
174192 control_point_coordinates .Y (),\
175193 control_point_coordinates .Z ()]
176-
177- #control_point = gp_Pnt(control_point_coordinates.X(),\
178- #control_point_coordinates.Y(),control_point_coordinates.Z())
179- #display.DisplayShape(BRepBuilderAPI_MakeVertex(control_point).Vertex(),update=True)
180- #print("Original: ",control_point.X()," ",control_point.Y()," ",control_point.Z())
181194 i += 1
182-
183195
184- #orig_control_polygon_coordinates = deepcopy(control_polygon_coordinates)
185196 ## SURFACES PHASE #####################################################
186197 src_pts = control_polygon_coordinates
187198 new_pts = super ().__call__ (src_pts ) # dont touch this line
199+
188200 i = 0
189201 for pole_u_direction in range (n_poles_u ):
190202 for pole_v_direction in range (n_poles_v ):
191- control_point = gp_Pnt (control_polygon_coordinates [i ,0 ],
192- control_polygon_coordinates [i ,1 ],
193- control_polygon_coordinates [i ,2 ])
203+ control_point = gp_Pnt (new_pts [i ,0 ],
204+ new_pts [i ,1 ],
205+ new_pts [i ,2 ])
194206 occ_face .SetPole (pole_u_direction + 1 , pole_v_direction + 1 , control_point )
195207 i += 1
196208 # through moving the control points, we now changed the SURFACE of the FACE we are processing
197209 # we now need to obtain the curves (actually, the WIRES) that define the bounds of the surface and TRIM the surface
198210 # with them, to obtain the new face
199211
200- faceFilling = BRepFill_Filling ()
201212 # we start creating a face with the modified surface. we will cut this new face with all the wires
202213 # that the original face had
203214 brep = BRepBuilderAPI_MakeFace (occ_face .GetHandle (), tol ).Face ()
204- #IGESControl_Controller_Init()
205- #writer = IGESControl_Writer()
206- #writer.AddShape(brep)
207- #nomefile = "untrimmed_face"+str(faceCount)+".iges"
208- #writer.Write(nomefile)
215+
209216
210217 # we here start looping on the wires of the original face
211- # in this forst loop we do nothing but count the wires in this face
218+ # in this first loop we do nothing but count the wires in this face
212219 # few faces have more than one wire: if they have, it is because they have holes, and
213220 # if this is the case one wire is the outer, and the others are the inner ones.
214221 # the loop will also tell us which wire is the outer one
215222 wire_count = 0
216223 wire_explorer = TopExp_Explorer (face_aux , TopAbs_WIRE )
217224 while wire_explorer .More ():
218- wire = OCC . TopoDS . topods_Wire (wire_explorer .Current ())
225+ wire = topods_Wire (wire_explorer .Current ())
219226 if (wire == breptools_OuterWire (face_aux )):
220227 print ("Wire" , wire_count + 1 , "is outer wire" )
221228 wire_count += 1
222229 wire_explorer .Next ()
223230 print ("This face has " ,wire_count ," wires" )
224231
225232 #we now start really looping on the wires
233+ #we will create a single curve joining all the edges in the wire
234+ # the curve must be a bspline curve so we need to make conversions through all the way
226235 wire_count = 0
227236 outer_wires = []
228237 inner_wires = []
229238 brep_face = BRep_Tool .Surface (brep )
230239 wire_explorer = TopExp_Explorer (face_aux , TopAbs_WIRE )
231240 while wire_explorer .More ():
232- wire = OCC . TopoDS . topods_Wire (wire_explorer .Current ())
241+ wire = topods_Wire (wire_explorer .Current ())
233242 wire_count += 1
234243 h_bspline_edge = GeomConvert_CompCurveToBSplineCurve ()
235244 edge_explorer = TopExp_Explorer (wire , TopAbs_EDGE )
236245 edgesCount = 0
237246 while edge_explorer .More ():
238247 # performing some conversions to get the right format (BSplineSurface)
239248 #print("Edge in curve: ", edgesCount)
240- edge = OCC . TopoDS . topods_Edge (edge_explorer .Current ())
249+ edge = topods_Edge (edge_explorer .Current ())
241250 if (BRep_Tool .Degenerated (edge ) == False ):
242251 bspline_converter = BRepBuilderAPI_NurbsConvert (edge )
243252 bspline_converter .Perform (edge )
244253 bspline_tshape_edge = bspline_converter .Shape ()
245- h_geom_edge , a , b = BRep_Tool_Curve (OCC . TopoDS . topods_Edge (bspline_tshape_edge ))
254+ h_geom_edge , a , b = BRep_Tool_Curve (topods_Edge (bspline_tshape_edge ))
246255 this_bspline_edge = geomconvert_CurveToBSplineCurve (h_geom_edge )
247256 bspline_geom_edge = this_bspline_edge .GetObject ()
248257 h_bspline_edge .Add (this_bspline_edge ,1e-4 )
@@ -253,29 +262,11 @@ def __call__(self, obj):
253262 bspline_geom_hedge = h_bspline_edge .BSplineCurve ()
254263 bspline_geom_edge = bspline_geom_hedge .GetObject ()
255264 unified_edge = BRepBuilderAPI_MakeEdge (bspline_geom_hedge ).Edge ()
256- #aa = bspline_geom_edge.FirstParameter()
257- #bb = bspline_geom_edge.LastParameter()
258- #print("Unif. Edge First Point:", bspline_geom_edge.Value(aa).X(),
259- #bspline_geom_edge.Value(aa).Y(),
260- #bspline_geom_edge.Value(aa).Z())
261- #print("Unif. Edge Last Point:", bspline_geom_edge.Value(bb).X(),
262- #bspline_geom_edge.Value(bb).Y(),
263- #bspline_geom_edge.Value(bb).Z())
264- #unified_edge = BRepBuilderAPI_MakeEdge(bspline_geom_hedge).Edge()
265- #print("SAVING UNIFIED CURVE: ", curve_count)
266- #IGESControl_Controller_Init()
267- #writer = IGESControl_Writer()
268- #writer.AddShape(unified_edge)
269- #filename = nomedir+"unfied_curve_"+str(curve_count)+".iges"
270- ##print(filename)
271- #writer.Write(filename)
272-
273265
266+ # number of knots is enriched here: this can become a user prescribed parameter for the class
267+ knotsToAdd = 200
274268 firstParam = bspline_geom_edge .FirstParameter ()
275269 lastParam = bspline_geom_edge .LastParameter ()
276- #print("First Parameter: ", firstParam)
277- #print("Last Parameter: ", lastParam)
278- knotsToAdd = 200
279270 for i in range (knotsToAdd ):
280271 bspline_geom_edge .InsertKnot (firstParam + i * (lastParam - firstParam )/ knotsToAdd ,1 ,1e-7 )
281272 shapesList = TopTools_ListOfShape ()
@@ -286,7 +277,6 @@ def __call__(self, obj):
286277 n_poles = occ_edge .NbPoles ()
287278 control_polygon_coordinates = np .zeros (\
288279 shape = (n_poles , 3 ))
289- #print("Number of poles: ", n_poles)
290280 # cycle over the poles to get their coordinates. The idea here is to move poles
291281 # coordinates to deform the curves
292282 i = 0
@@ -295,44 +285,29 @@ def __call__(self, obj):
295285 control_polygon_coordinates [i , :] = [control_point_coordinates .X (),\
296286 control_point_coordinates .Y (),\
297287 control_point_coordinates .Z ()]
298- #control_point = gp_Pnt(control_point_coordinates.X(),\
299- #control_point_coordinates.Y(),control_point_coordinates.Z())
300- #orig_control_point = control_point
301- #display.DisplayShape(BRepBuilderAPI_MakeVertex(control_point).Vertex(),update=True)
302- #print("Original: ",control_point.X()," ",control_point.Y()," ",control_point.Z())
288+ i += 1
303289
304290 ## CURVES PHASE #######################################################
305- src_pts = control_point_coordinates
306-
291+ src_pts = control_polygon_coordinates
307292 new_pts = super ().__call__ (src_pts ) # dont touch this line
308-
309293 # save here the `new_pts` into the shape
310294 ## END CURVES #########################################################
311295
312296 i = 0
313297 for pole in range (n_poles ):
314- #print("Function test:", mod_test_control_point.X(),mod_test_control_point.Y(),mod_test_control_point.Z())
315- #print("**")
316- control_point = gp_Pnt (control_polygon_coordinates [i ,0 ],
317- control_polygon_coordinates [i ,1 ],
318- control_polygon_coordinates [i ,2 ])
298+ control_point = gp_Pnt (new_pts [i ,0 ],
299+ new_pts [i ,1 ],
300+ new_pts [i ,2 ])
319301 occ_edge .SetPole (pole + 1 , control_point )
320302 i += 1
321303
322- #occ_new_hedge = geomprojlib.Project(occ_edge.GetHandle(),occ_face.GetHandle())
323- #new_curve = occ_new_hedge.GetObject()
324- #print("??", new_curve.IsClosed())
325304 modified_edge = BRepBuilderAPI_MakeEdge (occ_edge .GetHandle ()).Edge ()
326305 shapesList .Append (modified_edge )
327- #if new_curve.IsClosed()==False:
328- #fixer_edge = BRepBuilderAPI_MakeEdge(new_curve.Value(new_curve.LastParameter()),new_curve.Value(new_curve.FirstParameter())).Edge()
329- #shapesList.Append(fixer_edge)
330- #display.DisplayShape(modified_edge,update=True,color="BLUE1")
331-
306+
332307 wire_maker = BRepBuilderAPI_MakeWire ()
333308 wire_maker .Add (shapesList )
334309 result_wire = wire_maker .Wire ()
335-
310+
336311
337312 # now, the wire can be oute or inner. we store the outer and (possible) inner ones in different lists
338313 # this is because we first need to trim the surface using the outer wire, and then we can trim it
@@ -344,10 +319,6 @@ def __call__(self, obj):
344319 wire_count += 1
345320 wire_explorer .Next ()
346321
347- #faceFilling.LoadInitSurface(brep)
348- #faceFilling.Build()
349- # checking if things worked out
350- #print("Is face Filling Done? ",faceFilling.IsDone())
351322
352323 # so once we finished looping on all the wires to modify them, we use the only outer one to trim the surface
353324 face_maker = BRepBuilderAPI_MakeFace (occ_face .GetHandle (),outer_wires [0 ])
@@ -358,12 +329,10 @@ def __call__(self, obj):
358329
359330 # finally, we get our trimmed face with all its holes
360331 brep_surf = face_maker .Face ()
361- #brep_surf = faceFilling.Face()
362- #IGESControl_Controller_Init()
363- #writer = IGESControl_Writer()
364- #writer.AddShape(brep_surf)
365- #nomefile = nomedir+"trimmed_face"+str(faceCount)+".iges"
366- #writer.Write(nomefile)
332+
333+
334+ compound_builder .Add (compound , brep_surf )
335+ face_list .append (brep_surf )
367336
368337
369338 # and move to the next face
@@ -379,7 +348,9 @@ def __call__(self, obj):
379348
380349
381350
382- if isinstance (obj , str ): # if a input filename is passed
383- # save the shape exactly to the filename, aka `obj`
384- elif isinstance (obj , TopoDS_Shape ):
385- return shape
351+ if isinstance (dst , str ): # if a input filename is passed
352+ # save the shape exactly to the filename, aka `dst`
353+ iges_handler = IgesHandler ()
354+ iges_handler .write_shape_to_file (compound , dst )
355+ else :
356+ return compound
0 commit comments