mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 15:08:51 +00:00
IfcRelSpaceBoundary: Add error handling and better error message for user
This commit is contained in:
@@ -63,7 +63,8 @@ def disable_editing_boundary_geometry(context):
|
|||||||
|
|
||||||
|
|
||||||
class Loader:
|
class Loader:
|
||||||
def __init__(self):
|
def __init__(self, operator=None):
|
||||||
|
self.operator = operator
|
||||||
self.ifc_file = None
|
self.ifc_file = None
|
||||||
self.logger = None
|
self.logger = None
|
||||||
self.ifc_importer = None
|
self.ifc_importer = None
|
||||||
@@ -85,12 +86,18 @@ class Loader:
|
|||||||
tool.Loader.link_mesh(shape, mesh)
|
tool.Loader.link_mesh(shape, mesh)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
# Fallback solution for invalid geometry provided by Revit. (InnerBoundaries cuting OuterBoundary)
|
# Fallback solution for invalid geometry provided by Revit. (InnerBoundaries cuting OuterBoundary)
|
||||||
print(f"Failed to create mesh from IfcRelSpaceBoundary with ID {boundary.id()}. Geometry might be invalid")
|
self.operator.report(
|
||||||
|
{"WARNING"},
|
||||||
|
(
|
||||||
|
f"IfcRelSpaceBoundary {boundary.id()} mesh creation failed. Geometry might be invalid. Using fallback solution"
|
||||||
|
),
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
shape = ifcopenshell.geom.create_shape(self.fallback_settings, surface.OuterBoundary)
|
shape = ifcopenshell.geom.create_shape(self.fallback_settings, surface.OuterBoundary)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
print(
|
self.operator.report(
|
||||||
f"Skipping IfcRelSpaceBoundary with ID {boundary.id()}. Fallback solution failed. Geometry might be invalid"
|
{"WARNING"},
|
||||||
|
f"Skipping IfcRelSpaceBoundary {boundary.id()}. Fallback solution failed. Geometry might be invalid",
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
mesh = bpy.data.meshes.new(str(surface.id()))
|
mesh = bpy.data.meshes.new(str(surface.id()))
|
||||||
@@ -101,8 +108,9 @@ class Loader:
|
|||||||
try:
|
try:
|
||||||
shape = ifcopenshell.geom.create_shape(self.fallback_settings, inner_boundary)
|
shape = ifcopenshell.geom.create_shape(self.fallback_settings, inner_boundary)
|
||||||
except RuntimeError:
|
except RuntimeError:
|
||||||
print(
|
self.operator.report(
|
||||||
f"Skipping an inner boundary for IfcRelSpaceBoundary with ID {boundary.id()}. Geometry might be invalid"
|
{"WARNING"},
|
||||||
|
f"Skipping an inner boundary for IfcRelSpaceBoundary with ID {boundary.id()}. Geometry might be invalid",
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
verts = [bm.verts.new(shape.verts[i : i + 3]) for i in range(0, len(shape.verts), 3)]
|
verts = [bm.verts.new(shape.verts[i : i + 3]) for i in range(0, len(shape.verts), 3)]
|
||||||
@@ -138,7 +146,15 @@ class Loader:
|
|||||||
self.ifc_importer = import_ifc.IfcImporter(ifc_import_settings)
|
self.ifc_importer = import_ifc.IfcImporter(ifc_import_settings)
|
||||||
self.ifc_importer.file = self.ifc_file
|
self.ifc_importer.file = self.ifc_file
|
||||||
|
|
||||||
def load_boundary(self, boundary, blender_space):
|
def load_boundary(self, boundary, blender_space=None):
|
||||||
|
if not blender_space:
|
||||||
|
if not boundary.RelatingSpace:
|
||||||
|
self.operator.report(
|
||||||
|
{"WARNING"},
|
||||||
|
f"Skipping IfcRelSpaceBoundary {boundary.id()} which have no relating space. Invalid boundary.",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
blender_space = tool.Ifc.get_object(boundary.RelatingSpace)
|
||||||
obj = tool.Ifc.get_object(boundary)
|
obj = tool.Ifc.get_object(boundary)
|
||||||
if obj:
|
if obj:
|
||||||
return obj
|
return obj
|
||||||
@@ -157,9 +173,9 @@ class LoadProjectSpaceBoundaries(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
loader = Loader()
|
loader = Loader(self)
|
||||||
for rel in tool.Ifc.get().by_type("IfcRelSpaceBoundary"):
|
for rel in tool.Ifc.get().by_type("IfcRelSpaceBoundary"):
|
||||||
loader.load_boundary(rel, tool.Ifc.get_object(rel.RelatingSpace))
|
loader.load_boundary(rel)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -170,7 +186,7 @@ class LoadBoundary(bpy.types.Operator):
|
|||||||
boundary_id: bpy.props.IntProperty()
|
boundary_id: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
loader = Loader()
|
loader = Loader(self)
|
||||||
for obj in context.visible_objects:
|
for obj in context.visible_objects:
|
||||||
obj.select_set(False)
|
obj.select_set(False)
|
||||||
obj = loader.load_boundary(tool.Ifc.get().by_id(self.boundary_id), context.active_object)
|
obj = loader.load_boundary(tool.Ifc.get().by_id(self.boundary_id), context.active_object)
|
||||||
@@ -185,7 +201,7 @@ class LoadSpaceBoundaries(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
loader = Loader()
|
loader = Loader(self)
|
||||||
element = tool.Ifc.get_entity(context.active_object)
|
element = tool.Ifc.get_entity(context.active_object)
|
||||||
for rel in element.BoundedBy or []:
|
for rel in element.BoundedBy or []:
|
||||||
loader.load_boundary(rel, context.active_object)
|
loader.load_boundary(rel, context.active_object)
|
||||||
@@ -471,7 +487,7 @@ class EditBoundaryGeometry(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_surface)
|
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_surface)
|
||||||
|
|
||||||
old_mesh = obj.data
|
old_mesh = obj.data
|
||||||
loader = Loader()
|
loader = Loader(self)
|
||||||
obj.data = loader.create_mesh(element)
|
obj.data = loader.create_mesh(element)
|
||||||
tool.Geometry.delete_data(old_mesh)
|
tool.Geometry.delete_data(old_mesh)
|
||||||
|
|
||||||
@@ -496,7 +512,7 @@ class ShowBoundaries(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = bpy.context.scene.BIMBoundaryProperties
|
props = bpy.context.scene.BIMBoundaryProperties
|
||||||
loader = Loader()
|
loader = Loader(self)
|
||||||
for obj in context.selected_objects:
|
for obj in context.selected_objects:
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
if not element or not getattr(element, "BoundedBy", None):
|
if not element or not getattr(element, "BoundedBy", None):
|
||||||
|
|||||||
Reference in New Issue
Block a user