@@ -152,7 +152,6 @@ def __init__(self):
152152 self .ifc_filenames = []
153153 self .ifc_files = {}
154154 self .resolved_pixels = set ()
155- self .should_get_background = False
156155 self .text_pickle_file = "text.pickle"
157156 self .metadata_pickle_file = "metadata.pickle"
158157 self .cut_pickle_file = "cut.pickle"
@@ -192,15 +191,6 @@ def cut(self):
192191 self .get_cut_polygon_metadata ()
193192 self .profile_code ("Get cut polygon metadata" )
194193
195- # should_get_background is False in production as this is experimental
196- if not self .should_get_background :
197- return
198-
199- self .get_background_elements ()
200- self .sort_background_elements (reverse = True )
201- self .merge_background_elements ()
202- self .sort_background_elements ()
203-
204194 def profile_code (self , message ):
205195 if not self .time :
206196 self .time = time .time ()
@@ -329,76 +319,6 @@ def has_annotation(self, element):
329319 return True
330320 return False
331321
332- def sort_background_elements (self , reverse = None ):
333- if reverse :
334- new_list = sorted (self .background_elements , key = lambda k : - k ["z" ])
335- else :
336- new_list = sorted (self .background_elements , key = lambda k : k ["z" ])
337- self .background_elements = new_list
338-
339- def process_grid (self , face , resolution ):
340- try :
341- bbox = self .get_bbox (face )
342- xmin , ymin , zmin , xmax , ymax , zmax = bbox .Get ()
343- except :
344- return
345- current_x = 0
346- current_y = 0
347- is_visible = False
348- while current_x < self .section_box ["x" ]:
349- current_y = 0
350- while current_y > - self .section_box ["y" ]:
351- if current_x < xmin or current_x > xmax or current_y < ymin or current_y > ymax :
352- current_y -= resolution
353- continue
354- if (current_x , current_y ) in self .resolved_pixels :
355- current_y -= resolution
356- continue
357- point = numpy .array ((current_x , current_y , 0 ))
358- hit = self .raycast (face , point )
359- if hit :
360- is_visible = True
361- self .resolved_pixels .add ((current_x , current_y ))
362- current_y -= resolution
363- current_x += resolution
364- return is_visible
365-
366- def merge_background_elements (self ):
367- background_elements = []
368-
369- resolution = 0.1 # 10cm
370-
371- # DO CUT
372- total_product_shapes = len (self .cut_polygons )
373- n = 0
374- for element in self .cut_polygons :
375- # print('{}/{} background elements processed ...'.format(n, total_product_shapes), end='\r', flush=True)
376- print ("{}/{} cut polygons processed ..." .format (n , total_product_shapes ))
377- print ("{} resolved pixels" .format (len (self .resolved_pixels )))
378- n += 1
379- self .process_grid (element ["geometry_face" ], resolution )
380-
381- # DO BACKGROUND
382- total_product_shapes = len (self .background_elements )
383- n = 0
384- for element in self .background_elements :
385- # print('{}/{} background elements processed ...'.format(n, total_product_shapes), end='\r', flush=True)
386- print ("{}/{} background elements processed ..." .format (n , total_product_shapes ))
387- print ("{} resolved pixels" .format (len (self .resolved_pixels )))
388- n += 1
389- if element ["type" ] != "polygon" :
390- background_elements .append (element )
391- continue
392- is_visible = self .process_grid (element ["geometry_face" ], resolution )
393- if is_visible :
394- background_elements .append (element )
395-
396- print (
397- "##### BEFORE it had {} and after it had {}" .format (len (self .background_elements ), len (background_elements ))
398- )
399- self .background_elements = background_elements
400- return
401-
402322 def create_section_box (self ):
403323 top_left_corner = gp .gp_Pnt (
404324 self .section_box ["top_left_corner" ][0 ],
@@ -429,86 +349,6 @@ def create_section_box(self):
429349 self .transformation = gp .gp_Trsf ()
430350 self .transformation .SetDisplacement (source , destination )
431351
432- def get_background_elements (self ):
433- total_product_shapes = len (self .product_shapes )
434- n = 0
435- intersections = []
436- compound = TopoDS .TopoDS_Compound ()
437- builder = BRep .BRep_Builder ()
438- builder .MakeCompound (compound )
439- for product , shape in self .product_shapes :
440- builder .Add (compound , shape )
441-
442- print ("{}/{} background elements processed ..." .format (n , total_product_shapes ), end = "\r " , flush = True )
443- # print('Processing product {} '.format(product.Name))
444- n += 1
445-
446- intersection = BRepAlgoAPI .BRepAlgoAPI_Common (self .section_box ["shape" ], shape ).Shape ()
447- intersection_edges = self .get_booleaned_edges (intersection )
448- if len (intersection_edges ) <= 0 :
449- continue
450- intersections .append (intersection )
451-
452- transformed_intersection = BRepBuilderAPI .BRepBuilderAPI_Transform (intersection , self .transformation )
453- intersection = transformed_intersection .Shape ()
454-
455- edge_face_map = TopTools .TopTools_IndexedDataMapOfShapeListOfShape ()
456- TopExp .topexp .MapShapesAndAncestors (intersection , TopAbs .TopAbs_EDGE , TopAbs .TopAbs_FACE , edge_face_map )
457-
458- exp = TopExp .TopExp_Explorer (intersection , TopAbs .TopAbs_FACE )
459- while exp .More ():
460- face = topods .Face (exp .Current ())
461- normal = self .get_normal (face )
462- # Cull back-faces
463- if normal .Z () <= 0 :
464- exp .Next ()
465- continue
466- zpos , zmax = self .calculate_face_zpos (face )
467- self .build_new_face (face , zpos , product )
468- self .get_split_edges (edge_face_map , face , zmax , product )
469- exp .Next ()
470-
471- def get_raycast_hits (self , shape ):
472- resolution = 0.1 # 5cm
473- hits = []
474- current_x = 0
475- current_y = 0
476- while current_x < self .section_box ["x" ] / 2 :
477- current_y = 0
478- while current_y < self .section_box ["y" ] / 4 :
479- point = numpy .array (self .section_box ["top_left_corner" ])
480- point = numpy .add (point , current_x * numpy .array (self .section_box ["x_axis" ]))
481- point = numpy .add (point , current_y * numpy .array (self .section_box ["y_axis" ]))
482- hit = self .raycast (shape , point )
483- if hit :
484- hits .append (hit )
485- current_y += resolution
486- current_x += resolution
487- print ("row down" )
488- return hits
489-
490- def raycast (self , shape , point ):
491- raycast = IntCurvesFace .IntCurvesFace_ShapeIntersector ()
492- raycast .Load (shape , 0.01 )
493- line = gp .gp_Lin (gp .gp_Pnt (float (point [0 ]), float (point [1 ]), float (point [2 ])), gp .gp_Dir (0 , 0 , - 1 ))
494- raycast .Perform (line , 0 , self .section_box ["z" ])
495- return raycast .NbPnt () != 0
496-
497- def raycast_at_projection_dir (self , shape , point ):
498- raycast = IntCurvesFace .IntCurvesFace_ShapeIntersector ()
499- raycast .Load (shape , 0.01 )
500- line = gp .gp_Lin (
501- gp .gp_Pnt (float (point [0 ]), float (point [1 ]), float (point [2 ])),
502- gp .gp_Dir (
503- self .section_box ["projection" ][0 ], self .section_box ["projection" ][1 ], self .section_box ["projection" ][2 ]
504- ),
505- )
506- raycast .Perform (line , 0 , self .section_box ["z" ])
507- if raycast .NbPnt () != 0 :
508- # The smaller WParameter is the closer z-index
509- # Should be the first
510- return {"face" : raycast .Face (1 ), "z" : raycast .WParameter (1 )}
511-
512352 def get_bbox (self , shape ):
513353 bbox = Bnd .Bnd_Box ()
514354 BRepBndLib .brepbndlib_Add (shape , bbox )
@@ -520,111 +360,6 @@ def calculate_face_zpos(self, face):
520360 zpos = zmin + ((zmax - zmin ) / 2 )
521361 return zpos , zmax
522362
523- def get_split_edges (self , edge_face_map , face , zmax , product ):
524- exp2 = TopExp .TopExp_Explorer (face , TopAbs .TopAbs_EDGE )
525- while exp2 .More ():
526- edge = topods .Edge (exp2 .Current ())
527- adjface = TopoDS .TopoDS_Face ()
528- getadj = TopOpeBRepBuild .TopOpeBRepBuild_Tools .GetAdjacentFace (face , edge , edge_face_map , adjface )
529- if getadj :
530- try :
531- edge_angle = math .degrees (self .get_angle_between_faces (face , adjface ))
532- except :
533- # TODO: Figure out when a math domain error might occur,
534- # because it does, sometimes.
535- edge_angle = 0
536- if edge_angle > 30 and edge_angle < 160 :
537- newedge = self .build_new_edge (edge , zmax + 0.01 )
538- if newedge :
539- self .background_elements .append (
540- {"raw" : product , "geometry" : newedge , "type" : "line" , "z" : zmax + 0.01 }
541- )
542- exp2 .Next ()
543-
544- def get_angle_between_faces (self , f1 , f2 ):
545- return self .convert_dot_product_to_angle (
546- self .get_dot_product_of_normals (self .get_normal (f1 ), self .get_normal (f2 ))
547- )
548-
549- def get_normal (self , face ):
550- surface = Geom .Handle_Geom_Surface (BRep .BRep_Tool .Surface (face ))
551- props = GeomLProp .GeomLProp_SLProps (surface , 0 , 0 , 1 , 0.001 )
552- return props .Normal ()
553-
554- def get_dot_product_of_normals (self , n1 , n2 ):
555- return n1 .X () * n2 .X () + n1 .Y () * n2 .Y () + n1 .Z () * n2 .Z ()
556-
557- def convert_dot_product_to_angle (self , dp ):
558- return math .acos (dp )
559-
560- def is_same_point (self , p1 , p2 ):
561- return p1 .X () == p2 .X () and p1 .Y () == p2 .Y () and p1 .Z () == p2 .Z ()
562-
563- def build_new_edge (self , edge , zpos ):
564- exp = TopExp .TopExp_Explorer (edge , TopAbs .TopAbs_VERTEX )
565- new_vertices = []
566- while exp .More ():
567- current_vertex = topods .Vertex (exp .Current ())
568- current_point = BRep .BRep_Tool .Pnt (current_vertex )
569- current_point .SetZ (zpos )
570- new_vertices .append (BRepBuilderAPI .BRepBuilderAPI_MakeVertex (current_point ).Vertex ())
571- exp .Next ()
572- try :
573- return BRepBuilderAPI .BRepBuilderAPI_MakeEdge (new_vertices [0 ], new_vertices [1 ]).Edge ()
574- except :
575- return None
576-
577- def build_new_face (self , face , zpos , product ):
578- exp = TopExp .TopExp_Explorer (face , TopAbs .TopAbs_WIRE )
579- while exp .More ():
580- wireexp = BRepTools .BRepTools_WireExplorer (topods .Wire (exp .Current ()))
581- new_wire_builder = BRepBuilderAPI .BRepBuilderAPI_MakeWire ()
582- first_vertex = None
583- previous_vertex = None
584- while wireexp .More ():
585- current_vertex = wireexp .CurrentVertex ()
586- current_point = BRep .BRep_Tool .Pnt (current_vertex )
587- # Dodgy technique to squash in Z axis
588- current_point .SetZ (zpos )
589- current_vertex = BRepBuilderAPI .BRepBuilderAPI_MakeVertex (current_point ).Vertex ()
590- if not first_vertex :
591- first_vertex = current_vertex
592- if not previous_vertex :
593- previous_vertex = current_vertex
594- else :
595- try :
596- new_wire_builder .Add (
597- topods .Edge (BRepBuilderAPI .BRepBuilderAPI_MakeEdge (previous_vertex , current_vertex ).Edge ())
598- )
599- previous_vertex = current_vertex
600- except :
601- pass
602- wireexp .Next ()
603-
604- # make last edge
605- if not wireexp .More ():
606- try :
607- new_wire_builder .Add (
608- topods .Edge (BRepBuilderAPI .BRepBuilderAPI_MakeEdge (current_vertex , first_vertex ).Edge ())
609- )
610- except :
611- pass
612- try :
613- new_wire = new_wire_builder .Wire ()
614- new_face = BRepBuilderAPI .BRepBuilderAPI_MakeFace (new_wire ).Face ()
615- self .background_elements .append (
616- {"raw" : product , "geometry" : new_wire , "geometry_face" : new_face , "type" : "polygon" , "z" : zpos }
617- )
618- except :
619- # print('Could not build face')
620- pass
621- exp .Next ()
622-
623- def get_area (self , shape ):
624- gprops = GProp .GProp_GProps ()
625- BRepGProp .brepgprop .SurfaceProperties (shape , gprops )
626- return gprops .Mass ()
627-
628363 def get_booleaned_edges (self , shape ):
629364 edges = []
630365 exp = TopExp .TopExp_Explorer (shape , TopAbs .TopAbs_EDGE )
@@ -798,55 +533,3 @@ def get_pickled_cut_polygons(self):
798533 if os .path .isfile (self .cut_pickle_file ):
799534 with open (self .cut_pickle_file , "rb" ) as pickle_file :
800535 self .cut_polygons = pickle .load (pickle_file )
801-
802-
803- class IfcCutterDebug (IfcCutter ):
804- def cut (self ):
805- self .occ_display = ifcopenshell .geom .utils .initialize_display ()
806- super ().cut ()
807-
808- def create_section_box (self ):
809- super ().create_section_box ()
810- self .display_everything_with_section_plane ()
811-
812- def get_cut_polygons (self ):
813- super ().get_cut_polygons ()
814- self .display_cut_polygons ()
815-
816- def get_background_elements (self ):
817- super ().get_background_elements ()
818- self .display_background_elements ()
819-
820- def display_everything_with_section_plane (self ):
821- section_face_display = ifcopenshell .geom .utils .display_shape (self .section_box ["face" ])
822- ifcopenshell .geom .utils .set_shape_transparency (section_face_display , 0.8 )
823- section_box_display = ifcopenshell .geom .utils .display_shape (self .section_box ["shape" ])
824- ifcopenshell .geom .utils .set_shape_transparency (section_box_display , 0.5 )
825-
826- transformed_box = BRepBuilderAPI .BRepBuilderAPI_Transform (self .section_box ["shape" ], self .transformation )
827- box_display = ifcopenshell .geom .utils .display_shape (transformed_box .Shape ())
828- ifcopenshell .geom .utils .set_shape_transparency (box_display , 0.2 )
829-
830- for shape in self .product_shapes :
831- ifcopenshell .geom .utils .display_shape (shape [1 ])
832- input ("Debug: showing everything with section plane." )
833-
834- def display_cut_polygons (self ):
835- self .occ_display .EraseAll ()
836- for polygon in self .cut_polygons :
837- ifcopenshell .geom .utils .display_shape (polygon ["geometry" ], clr = "BLACK" )
838- face = BRepBuilderAPI .BRepBuilderAPI_MakeFace (polygon ["geometry" ]).Face ()
839- face_display = ifcopenshell .geom .utils .display_shape (face )
840- ifcopenshell .geom .utils .set_shape_transparency (face_display , 0.5 )
841- input ("Debug: showing cut polygons." )
842-
843- def display_background_elements (self ):
844- self .occ_display .EraseAll ()
845- for element in self .background_elements :
846- if element ["type" ] == "line" :
847- ifcopenshell .geom .utils .display_shape (element ["geometry" ], clr = "PURPLE" )
848- elif element ["type" ] == "polyline" :
849- ifcopenshell .geom .utils .display_shape (element ["geometry_face" ], clr = "RED" )
850- elif element ["type" ] == "polygon" :
851- ifcopenshell .geom .utils .display_shape (element ["geometry_face" ])
852- input ("Debug: showing background elements." )
0 commit comments