#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",
}
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.
# Commented out as seems currently too slow.
# if self.is_native_faceted_brep(representations):
# self.native_data[element.GlobalId] = {
# "representations": representations,
# "representation": self.get_body_representation(element.Representation.Representations),
# "type": "IfcFacetedBrep",
# }
# return True
if self.is_native_faceted_brep(representations):
self.native_data[element.GlobalId] = {
"representations": representations,
"representation": self.get_body_representation(element.Representation.Representations),
"type": "IfcFacetedBrep",
}
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):
for representation in representations:
@@ -388,6 +399,13 @@ class IfcImporter:
return False
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):
products = [pr.ShapeOfProduct[0] for pr in element.OfProductRepresentation]
for rep_map in element.RepresentationMap:
@@ -619,6 +637,8 @@ class IfcImporter:
mesh = self.create_native_swept_disk_solid(element, mesh_name)
elif native_data["type"] == "IfcFacetedBrep":
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.name = mesh_name
self.meshes[mesh_name] = mesh
@@ -935,22 +955,32 @@ class IfcImporter:
self.convert_representation(item.MappingSource.MappedRepresentation)
elif item.is_a() == "IfcFacetedBrep":
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):
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.
# 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()
# 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?
# 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)
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.
if len(face["Bounds"]) > 1:
inner_bounds = []
@@ -1888,6 +1918,7 @@ class IfcImportSettings:
self.should_merge_by_class = False
self.should_merge_by_material = False
self.should_merge_materials_by_colour = False
self.should_use_native_meshes = False
self.should_clean_mesh = True
self.deflection_tolerance = 0.001
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_material = props.should_merge_by_material
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.deflection_tolerance = props.deflection_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_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_use_native_meshes: BoolProperty(name="Native Meshes", default=False)
deflection_tolerance: FloatProperty(name="Deflection Tolerance", default=0.001)
angular_tolerance: FloatProperty(name="Angular Tolerance", default=0.5)
distance_limit: FloatProperty(name="Distance Limit", default=1000)
@@ -78,6 +78,7 @@ class BIM_PT_project(Panel):
row = self.layout.row()
row.prop(pprops, "should_merge_by_material")
row = self.layout.row()
row.prop(pprops, "should_use_native_meshes")
row.prop(pprops, "should_merge_materials_by_colour")
row = self.layout.row()
row.prop(pprops, "should_clean_mesh")