Skip parts without polygons converting mesh to tessellation #5870

As IFC doesn't allow mixed geometry types anyway.
This commit is contained in:
Andrej730
2024-12-13 15:37:59 +05:00
parent 34e8e8911d
commit 2251679479
2 changed files with 35 additions and 0 deletions
@@ -217,6 +217,12 @@ class AssignClass(bpy.types.Operator, tool.Ifc.Operator):
should_add_representation = False
export_mesh_to_tesselation = True
if tool.Geometry.mesh_has_loose_geometry(obj.data):
self.report(
{"WARNING"},
f"Mesh '{obj.data.name}' has loose geometry, loose geometry was be ignored to save mesh to IFC as a tessellation.",
)
element = core.assign_class(
tool.Ifc,
tool.Collector,
+29
View File
@@ -1727,6 +1727,10 @@ class Geometry(bonsai.core.tool.Geometry):
items = []
meshes = cls.split_by_loose_parts(obj)
for mesh in meshes:
# Skip parts that won't work for tessellation.
if not mesh.polygons:
bpy.data.meshes.remove(mesh)
continue
verts = [v.co / unit_scale for v in mesh.vertices]
faces = [p.vertices[:] for p in mesh.polygons]
item = builder.mesh(verts, faces)
@@ -1750,3 +1754,28 @@ class Geometry(bonsai.core.tool.Geometry):
ifcopenshell.api.style.assign_item_style(tool.Ifc.get(), item=item, style=style)
bpy.data.meshes.remove(mesh)
return builder.get_representation(ifc_context, items)
@classmethod
def mesh_has_loose_geometry(cls, mesh: bpy.types.Mesh) -> bool:
"""Check if mesh has loose geometry (edges without faces, verts without edges)."""
bm = tool.Blender.get_bmesh_for_mesh(mesh)
# Most of the time it will return `False`,
# so checking verts for being manifold
# should be the fastest way to proceed in those cases.
non_manifold_edges = set()
for vert in bm.verts:
if not vert.is_manifold:
# Not all non-manifold verts mean loose geometry
# e.g. a vert shared by 2 planes.
if not vert.link_faces:
return True
non_manifold_edges.update(vert.link_edges)
if not non_manifold_edges:
return False
for edge in non_manifold_edges:
if not edge.link_faces:
return True
return False