From 1515ef98b7e23cccee7f39d5db3aa2f846dd78db Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 15 Aug 2021 11:05:47 +1000 Subject: [PATCH] Walls and slabs (or any vertical or horziontal layer) now auto recalculate origins after editing --- .../blenderbim/bim/module/model/slab.py | 56 +++++++++++-------- .../blenderbim/bim/module/model/wall.py | 24 +++++--- 2 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/model/slab.py b/src/blenderbim/blenderbim/bim/module/model/slab.py index 997b2b2463..499ecba7af 100644 --- a/src/blenderbim/blenderbim/bim/module/model/slab.py +++ b/src/blenderbim/blenderbim/bim/module/model/slab.py @@ -20,10 +20,9 @@ def element_listener(element, obj): def mode_callback(obj, data): - for obj in bpy.context.selected_objects + [bpy.context.active_object]: + for obj in set(bpy.context.selected_objects + [bpy.context.active_object]): if ( - obj.mode != "EDIT" - or not obj.data + not obj.data or not isinstance(obj.data, (bpy.types.Mesh, bpy.types.Curve, bpy.types.TextCurve)) or not obj.BIMObjectProperties.ifc_definition_id or not bpy.context.scene.BIMProjectProperties.is_authoring @@ -33,27 +32,36 @@ def mode_callback(obj, data): parametric = ifcopenshell.util.element.get_psets(product).get("EPset_Parametric") if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer3": return - IfcStore.edited_objs.add(obj) - modifier = [m for m in obj.modifiers if m.type == "SOLIDIFY"] - if modifier: - return - depth = obj.dimensions.z - bm = bmesh.from_edit_mesh(obj.data) - bmesh.ops.dissolve_limit(bm, angle_limit=pi / 180 * 1, verts=bm.verts, edges=bm.edges) - bm.faces.ensure_lookup_table() - non_bottom_faces = [] - for face in bm.faces: - if face.normal.z > -0.9: - non_bottom_faces.append(face) - else: - face.normal_flip() - bmesh.ops.delete(bm, geom=non_bottom_faces, context="FACES") - bmesh.update_edit_mesh(obj.data) - bm.free() - modifier = obj.modifiers.new("Slab Depth", "SOLIDIFY") - modifier.use_even_offset = True - modifier.offset = 1 - modifier.thickness = depth + if obj.mode == "EDIT": + IfcStore.edited_objs.add(obj) + modifier = [m for m in obj.modifiers if m.type == "SOLIDIFY"] + if modifier: + return + depth = obj.dimensions.z + bm = bmesh.from_edit_mesh(obj.data) + bmesh.ops.dissolve_limit(bm, angle_limit=pi / 180 * 1, verts=bm.verts, edges=bm.edges) + bm.faces.ensure_lookup_table() + non_bottom_faces = [] + for face in bm.faces: + if face.normal.z > -0.9: + non_bottom_faces.append(face) + else: + face.normal_flip() + bmesh.ops.delete(bm, geom=non_bottom_faces, context="FACES") + bmesh.update_edit_mesh(obj.data) + bm.free() + modifier = obj.modifiers.new("Slab Depth", "SOLIDIFY") + modifier.use_even_offset = True + modifier.offset = 1 + modifier.thickness = depth + else: + new_origin = obj.matrix_world @ Vector(obj.bound_box[0]) + obj.data.transform( + Matrix.Translation( + (obj.matrix_world.inverted().to_quaternion() @ (obj.matrix_world.translation - new_origin)) + ) + ) + obj.matrix_world.translation = new_origin def ensure_solid(usecase_path, ifc_file, settings): diff --git a/src/blenderbim/blenderbim/bim/module/model/wall.py b/src/blenderbim/blenderbim/bim/module/model/wall.py index 0be02b718a..ebc556fabe 100644 --- a/src/blenderbim/blenderbim/bim/module/model/wall.py +++ b/src/blenderbim/blenderbim/bim/module/model/wall.py @@ -22,8 +22,7 @@ def element_listener(element, obj): def mode_callback(obj, data): for obj in set(bpy.context.selected_objects + [bpy.context.active_object]): if ( - obj.mode != "EDIT" - or not obj.data + not obj.data or not isinstance(obj.data, (bpy.types.Mesh, bpy.types.Curve, bpy.types.TextCurve)) or not obj.BIMObjectProperties.ifc_definition_id or not bpy.context.scene.BIMProjectProperties.is_authoring @@ -33,12 +32,21 @@ def mode_callback(obj, data): parametric = ifcopenshell.util.element.get_psets(product).get("EPset_Parametric") if not parametric or parametric["Engine"] != "BlenderBIM.DumbLayer2": return - bpy.ops.bim.dynamically_void_product(obj=obj.name) - IfcStore.edited_objs.add(obj) - bm = bmesh.from_edit_mesh(obj.data) - bmesh.ops.dissolve_limit(bm, angle_limit=pi / 180 * 1, verts=bm.verts, edges=bm.edges) - bmesh.update_edit_mesh(obj.data) - bm.free() + if obj.mode == "EDIT": + bpy.ops.bim.dynamically_void_product(obj=obj.name) + IfcStore.edited_objs.add(obj) + bm = bmesh.from_edit_mesh(obj.data) + bmesh.ops.dissolve_limit(bm, angle_limit=pi / 180 * 1, verts=bm.verts, edges=bm.edges) + bmesh.update_edit_mesh(obj.data) + bm.free() + else: + new_origin = obj.matrix_world @ Vector(obj.bound_box[0]) + obj.data.transform( + Matrix.Translation( + (obj.matrix_world.inverted().to_quaternion() @ (obj.matrix_world.translation - new_origin)) + ) + ) + obj.matrix_world.translation = new_origin class JoinWall(bpy.types.Operator):