#841 #2224 Users can now enable native mesh processing with support for FBSM geometry

This commit is contained in:
Dion Moult
2022-06-08 10:19:55 +10:00
parent 96e4641ebf
commit 4681d3198f
3 changed files with 45 additions and 11 deletions
+43 -11
View File
@@ -364,15 +364,26 @@ class IfcImporter:
"type": "IfcSweptDiskSolid", "type": "IfcSweptDiskSolid",
} }
return True return True
if not self.ifc_import_settings.should_use_native_meshes:
return False # Performance improvements only occur on edge cases currently
# FacetedBreps (without voids) are meshes. See #841. # FacetedBreps (without voids) are meshes. See #841.
# Commented out as seems currently too slow. if self.is_native_faceted_brep(representations):
# if self.is_native_faceted_brep(representations): self.native_data[element.GlobalId] = {
# self.native_data[element.GlobalId] = { "representations": representations,
# "representations": representations, "representation": self.get_body_representation(element.Representation.Representations),
# "representation": self.get_body_representation(element.Representation.Representations), "type": "IfcFacetedBrep",
# "type": "IfcFacetedBrep", }
# } return True
# return True
if self.is_native_face_based_surface_model(representations):
self.native_data[element.GlobalId] = {
"representations": representations,
"representation": self.get_body_representation(element.Representation.Representations),
"type": "IfcFaceBasedSurfaceModel",
}
return True
def is_native_swept_disk_solid(self, representations): def is_native_swept_disk_solid(self, representations):
for representation in representations: for representation in representations:
@@ -388,6 +399,13 @@ class IfcImporter:
return False return False
return True return True
def is_native_face_based_surface_model(self, representations):
for representation in representations:
for i in representation["raw"].Items:
if i.is_a() != "IfcFaceBasedSurfaceModel":
return False
return True
def get_products_from_shape_representation(self, element): def get_products_from_shape_representation(self, element):
products = [pr.ShapeOfProduct[0] for pr in element.OfProductRepresentation] products = [pr.ShapeOfProduct[0] for pr in element.OfProductRepresentation]
for rep_map in element.RepresentationMap: for rep_map in element.RepresentationMap:
@@ -619,6 +637,8 @@ class IfcImporter:
mesh = self.create_native_swept_disk_solid(element, mesh_name) mesh = self.create_native_swept_disk_solid(element, mesh_name)
elif native_data["type"] == "IfcFacetedBrep": elif native_data["type"] == "IfcFacetedBrep":
mesh = self.create_native_faceted_brep(element, mesh_name) mesh = self.create_native_faceted_brep(element, mesh_name)
elif native_data["type"] == "IfcFaceBasedSurfaceModel":
mesh = self.create_native_faceted_brep(element, mesh_name)
mesh.BIMMeshProperties.ifc_definition_id = representation.id() mesh.BIMMeshProperties.ifc_definition_id = representation.id()
mesh.name = mesh_name mesh.name = mesh_name
self.meshes[mesh_name] = mesh self.meshes[mesh_name] = mesh
@@ -935,22 +955,32 @@ class IfcImporter:
self.convert_representation(item.MappingSource.MappedRepresentation) self.convert_representation(item.MappingSource.MappedRepresentation)
elif item.is_a() == "IfcFacetedBrep": elif item.is_a() == "IfcFacetedBrep":
self.convert_representation_item_faceted_brep(item) self.convert_representation_item_faceted_brep(item)
elif item.is_a() == "IfcFaceBasedSurfaceModel":
self.convert_representation_item_face_based_surface_model(item)
def convert_representation_item_face_based_surface_model(self, item):
mesh = item.get_info_2(recursive=True)
for face_set in mesh["FbsmFaces"]:
self.convert_representation_item_face_set(item, face_set)
def convert_representation_item_faceted_brep(self, item): def convert_representation_item_faceted_brep(self, item):
mesh = item.get_info_2(recursive=True)
return self.convert_representation_item_face_set(item, mesh["Outer"])
def convert_representation_item_face_set(self, item, mesh):
# On a few occasions, we flatten a list. This seems to be the most efficient way to do it. # On a few occasions, we flatten a list. This seems to be the most efficient way to do it.
# https://stackoverflow.com/questions/20112776/how-do-i-flatten-a-list-of-lists-nested-lists # https://stackoverflow.com/questions/20112776/how-do-i-flatten-a-list-of-lists-nested-lists
mesh = item.get_info_2(recursive=True)
# For huge face sets it might be better to do a "flatmap" instead of sum() # For huge face sets it might be better to do a "flatmap" instead of sum()
# bounds = sum((f["Bounds"] for f in mesh["Outer"]["CfsFaces"] if len(f["Bounds"]) == 1), ()) # bounds = sum((f["Bounds"] for f in mesh["Outer"]["CfsFaces"] if len(f["Bounds"]) == 1), ())
bounds = tuple(chain.from_iterable(f["Bounds"] for f in mesh["Outer"]["CfsFaces"] if len(f["Bounds"]) == 1)) bounds = tuple(chain.from_iterable(f["Bounds"] for f in mesh["CfsFaces"] if len(f["Bounds"]) == 1))
# Here are some untested alternatives, are they faster? # Here are some untested alternatives, are they faster?
# bounds = tuple((f["Bounds"] for f in mesh["Outer"]["CfsFaces"] if len(f["Bounds"]) == 1))[0] # bounds = tuple((f["Bounds"] for f in mesh["Outer"]["CfsFaces"] if len(f["Bounds"]) == 1))[0]
# bounds = chain.from_iterable(f["Bounds"] for f in mesh["Outer"]["CfsFaces"] if len(f["Bounds"]) == 1) # bounds = chain.from_iterable(f["Bounds"] for f in mesh["Outer"]["CfsFaces"] if len(f["Bounds"]) == 1)
polygons = [[(p["id"], p["Coordinates"]) for p in b["Bound"]["Polygon"]] for b in bounds] polygons = [[(p["id"], p["Coordinates"]) for p in b["Bound"]["Polygon"]] for b in bounds]
for face in mesh["Outer"]["CfsFaces"]: for face in mesh["CfsFaces"]:
# Blender cannot handle faces with holes. # Blender cannot handle faces with holes.
if len(face["Bounds"]) > 1: if len(face["Bounds"]) > 1:
inner_bounds = [] inner_bounds = []
@@ -1888,6 +1918,7 @@ class IfcImportSettings:
self.should_merge_by_class = False self.should_merge_by_class = False
self.should_merge_by_material = False self.should_merge_by_material = False
self.should_merge_materials_by_colour = False self.should_merge_materials_by_colour = False
self.should_use_native_meshes = False
self.should_clean_mesh = True self.should_clean_mesh = True
self.deflection_tolerance = 0.001 self.deflection_tolerance = 0.001
self.angular_tolerance = 0.5 self.angular_tolerance = 0.5
@@ -1913,6 +1944,7 @@ class IfcImportSettings:
settings.should_merge_by_class = props.should_merge_by_class settings.should_merge_by_class = props.should_merge_by_class
settings.should_merge_by_material = props.should_merge_by_material settings.should_merge_by_material = props.should_merge_by_material
settings.should_merge_materials_by_colour = props.should_merge_materials_by_colour settings.should_merge_materials_by_colour = props.should_merge_materials_by_colour
settings.should_use_native_meshes = props.should_use_native_meshes
settings.should_clean_mesh = props.should_clean_mesh settings.should_clean_mesh = props.should_clean_mesh
settings.deflection_tolerance = props.deflection_tolerance settings.deflection_tolerance = props.deflection_tolerance
settings.angular_tolerance = props.angular_tolerance settings.angular_tolerance = props.angular_tolerance
@@ -132,6 +132,7 @@ class BIMProjectProperties(PropertyGroup):
should_merge_by_material: BoolProperty(name="Import and Merge by Material", default=False) should_merge_by_material: BoolProperty(name="Import and Merge by Material", default=False)
should_merge_materials_by_colour: BoolProperty(name="Import and Merge Materials by Colour", default=False) should_merge_materials_by_colour: BoolProperty(name="Import and Merge Materials by Colour", default=False)
should_clean_mesh: BoolProperty(name="Import and Clean Mesh", default=True) should_clean_mesh: BoolProperty(name="Import and Clean Mesh", default=True)
should_use_native_meshes: BoolProperty(name="Native Meshes", default=False)
deflection_tolerance: FloatProperty(name="Deflection Tolerance", default=0.001) deflection_tolerance: FloatProperty(name="Deflection Tolerance", default=0.001)
angular_tolerance: FloatProperty(name="Angular Tolerance", default=0.5) angular_tolerance: FloatProperty(name="Angular Tolerance", default=0.5)
distance_limit: FloatProperty(name="Distance Limit", default=1000) distance_limit: FloatProperty(name="Distance Limit", default=1000)
@@ -78,6 +78,7 @@ class BIM_PT_project(Panel):
row = self.layout.row() row = self.layout.row()
row.prop(pprops, "should_merge_by_material") row.prop(pprops, "should_merge_by_material")
row = self.layout.row() row = self.layout.row()
row.prop(pprops, "should_use_native_meshes")
row.prop(pprops, "should_merge_materials_by_colour") row.prop(pprops, "should_merge_materials_by_colour")
row = self.layout.row() row = self.layout.row()
row.prop(pprops, "should_clean_mesh") row.prop(pprops, "should_clean_mesh")