mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +00:00
Cleaning up connections on delete_ifc
Noticed an error if you connect wall and slab, then remove the slab and try to regenerate the wall - error occured because connection to that slab wasn't removed.
The error was:
Error: Python: Traceback (most recent call last):
File "\3.6\scripts\addons\blenderbim\bim\module\model\workspace.py", line 381, in invoke
return self.execute(context)
File "\3.6\scripts\addons\blenderbim\tool\ifc.py", line 136, in execute
IfcStore.execute_ifc_operator(self, context)
File "\3.6\scripts\addons\blenderbim\bim\ifc.py", line 421, in execute_ifc_operator
result = getattr(operator, "_execute")(context)
File "\3.6\scripts\addons\blenderbim\bim\module\model\workspace.py", line 373, in _execute
getattr(self, f"hotkey_{self.hotkey}")()
File "\3.6\scripts\addons\blenderbim\bim\module\model\workspace.py", line 465, in hotkey_S_E
bpy.ops.bim.join_wall(join_type="T")
File "C:\software\Steam\steamapps\common\Blender\3.6\scripts\modules\bpy\ops.py", line 113, in __call__
ret = _op_call(self.idname_py(), None, kw)
RuntimeError: Error: Python: Traceback (most recent call last):
File "\3.6\scripts\addons\blenderbim\tool\ifc.py", line 136, in execute
IfcStore.execute_ifc_operator(self, context)
File "\3.6\scripts\addons\blenderbim\bim\ifc.py", line 421, in execute_ifc_operator
result = getattr(operator, "_execute")(context)
File "\3.6\scripts\addons\blenderbim\bim\module\model\wall.py", line 76, in _execute
joiner.join_E(context.active_object, context.scene.cursor.location)
File "\3.6\scripts\addons\blenderbim\bim\module\model\wall.py", line 1038, in join_E
self.recreate_wall(element1, wall1, axis, body)
File "\3.6\scripts\addons\blenderbim\bim\module\model\wall.py", line 1145, in recreate_wall
height = self.clip(obj, tool.Ifc.get_object(rel.RelatingElement))
File "\3.6\scripts\addons\blenderbim\tool\ifc.py", line 89, in get_object
return IfcStore.get_element(element.id())
AttributeError: 'NoneType' object has no attribute 'id'
This commit is contained in:
@@ -60,11 +60,11 @@ class JoinWall(bpy.types.Operator, tool.Ifc.Operator):
|
||||
for obj in selected_objs:
|
||||
joiner.unjoin(obj)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
if not context.active_object or not context.active_object.BIMObjectProperties.ifc_definition_id:
|
||||
self.report({"ERROR"}, f"No active object selected")
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
for obj in selected_objs:
|
||||
tool.Geometry.clear_scale(obj)
|
||||
|
||||
@@ -75,7 +75,7 @@ class JoinWall(bpy.types.Operator, tool.Ifc.Operator):
|
||||
if len(selected_objs) == 1:
|
||||
joiner.join_E(context.active_object, context.scene.cursor.location)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
if self.join_type in ("L", "V"):
|
||||
if len(selected_objs) != 2:
|
||||
self.report({"ERROR"}, f"It requires 2 selected objects to do join of type {self.join_type}")
|
||||
@@ -86,7 +86,7 @@ class JoinWall(bpy.types.Operator, tool.Ifc.Operator):
|
||||
elif self.join_type == "V":
|
||||
joiner.join_V(another_selected_object, context.active_object)
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
if self.join_type == "T":
|
||||
elements = [tool.Ifc.get_entity(o) for o in context.selected_objects]
|
||||
layer2_elements = []
|
||||
@@ -560,7 +560,7 @@ class DumbWallGenerator:
|
||||
|
||||
rotation = math.atan2(normal[1], normal[0])
|
||||
rotated_y_axis = Matrix.Rotation(-rotation, 4, "Z")[1].xyz
|
||||
|
||||
|
||||
# since wall thickness goes by local Y+ axis
|
||||
# we find best position for the next wall
|
||||
# by finding the face of another wall that will be very close to the some test point.
|
||||
@@ -1137,7 +1137,7 @@ class DumbWallJoiner:
|
||||
|
||||
previous_matrix = obj.matrix_world.copy()
|
||||
previous_origin = previous_matrix.col[3].to_2d()
|
||||
obj.matrix_world[0][3], obj.matrix_world[1][3] = self.body[0]
|
||||
obj.matrix_world.col[3].xy = self.body[0]
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
for rel in element.ConnectedFrom:
|
||||
@@ -1432,6 +1432,7 @@ class DumbWallJoiner:
|
||||
return True
|
||||
|
||||
def clip(self, wall1, slab2):
|
||||
"""returns height of the clipped wall, adds clipping plane to `clippings`"""
|
||||
element1 = tool.Ifc.get_entity(wall1)
|
||||
element2 = tool.Ifc.get_entity(slab2)
|
||||
|
||||
@@ -1441,19 +1442,15 @@ class DumbWallJoiner:
|
||||
bases = [axis1["base"][0].to_3d(), axis1["base"][1].to_3d(), axis1["side"][0].to_3d(), axis1["side"][1].to_3d()]
|
||||
|
||||
extrusion = self.get_extrusion_data(tool.Ifc.get().by_id(wall1.data.BIMMeshProperties.ifc_definition_id))
|
||||
d = wall1.matrix_world.to_quaternion() @ extrusion["direction"]
|
||||
wall_dir = wall1.matrix_world.to_quaternion() @ extrusion["direction"]
|
||||
|
||||
slab_pt = slab2.matrix_world @ Vector((0, 0, 0))
|
||||
slab_dir = slab2.matrix_world.to_quaternion() @ Vector((0, 0, -1))
|
||||
|
||||
tops = [mathutils.geometry.intersect_line_plane(b, b + d, slab_pt, slab_dir) for b in bases]
|
||||
|
||||
i_bottom = None
|
||||
i_top = None
|
||||
for i, co in enumerate(tops):
|
||||
if i_top is None or co[2] > i_top[2]:
|
||||
i_top = co
|
||||
i_bottom = bases[i]
|
||||
tops = [mathutils.geometry.intersect_line_plane(b, b + wall_dir, slab_pt, slab_dir) for b in bases]
|
||||
top_index = max(range(4), key=lambda i: tops[i].z)
|
||||
i_top = tops[top_index]
|
||||
i_bottom = bases[top_index]
|
||||
|
||||
quaternion = slab2.matrix_world.to_quaternion()
|
||||
x_axis = quaternion @ Vector((1, 0, 0))
|
||||
|
||||
@@ -457,7 +457,7 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
if len(bpy.context.selected_objects) == 1:
|
||||
if self.active_material_usage == "LAYER3":
|
||||
# Edit LAYER2 profile
|
||||
# Edit LAYER3 profile
|
||||
if bpy.context.active_object and bpy.context.active_object.mode == "OBJECT":
|
||||
bpy.ops.bim.enable_editing_extrusion_profile()
|
||||
elif self.active_material_usage == "LAYER2":
|
||||
@@ -469,6 +469,7 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
else:
|
||||
# Edit SWEPTSOLID profile (assuming single profile for now)
|
||||
bpy.ops.bim.enable_editing_extrusion_profile()
|
||||
|
||||
elif self.active_material_usage == "LAYER2" and selected_usages.get("PROFILE", []):
|
||||
# Extend PROFILEs to LAYER2
|
||||
[o.select_set(False) for o in selected_usages.get("LAYER3", [])]
|
||||
|
||||
@@ -75,6 +75,12 @@ class Geometry(blenderbim.core.tool.Geometry):
|
||||
if element.is_a("IfcRelSpaceBoundary"):
|
||||
ifcopenshell.api.run("boundary.remove_boundary", tool.Ifc.get(), boundary=element)
|
||||
return bpy.data.objects.remove(obj)
|
||||
|
||||
if element.is_a("IfcElement"):
|
||||
connections = element.ConnectedTo + element.ConnectedFrom
|
||||
for connection in connections:
|
||||
tool.Ifc.get().remove(connection)
|
||||
|
||||
collection = obj.BIMObjectProperties.collection
|
||||
if collection:
|
||||
parent = ifcopenshell.util.element.get_aggregate(element)
|
||||
|
||||
Reference in New Issue
Block a user