From 04092d19be8aeb2bf66e488d7c76d7bb1e70ae51 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 12 Jan 2025 22:43:34 +1100 Subject: [PATCH] Refactor common function for parametric objects into tool.Model --- src/bonsai/bonsai/bim/module/model/door.py | 24 +++---------------- src/bonsai/bonsai/bim/module/model/railing.py | 9 ++++--- src/bonsai/bonsai/bim/module/model/roof.py | 3 +-- src/bonsai/bonsai/tool/model.py | 17 +++++++++++++ 4 files changed, 25 insertions(+), 28 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/model/door.py b/src/bonsai/bonsai/bim/module/model/door.py index 94ba825413..d8208feaea 100644 --- a/src/bonsai/bonsai/bim/module/model/door.py +++ b/src/bonsai/bonsai/bim/module/model/door.py @@ -19,8 +19,6 @@ import bpy import bmesh -from bmesh.types import BMVert, BMFace - import ifcopenshell import ifcopenshell.api import ifcopenshell.util.element @@ -169,22 +167,6 @@ def update_door_modifier_representation(obj: bpy.types.Object) -> None: tool.Model.update_simple_openings(element) -# TODO: move it out to tools -def bm_sort_out_geom( - geom_data: list[Union[bmesh.types.BMVert, bmesh.types.BMEdge, bmesh.types.BMFace]] -) -> dict[str, Any]: - geom_dict = {"verts": [], "edges": [], "faces": []} - - for el in geom_data: - if isinstance(el, BMVert): - geom_dict["verts"].append(el) - elif isinstance(el, BMFace): - geom_dict["faces"].append(el) - else: - geom_dict["edges"].append(el) - return geom_dict - - def bm_mirror( bm: bmesh.types.BMesh, verts: list[bmesh.types.BMVert], @@ -208,7 +190,7 @@ def bm_mirror( for v in verts: faces.update(v.link_faces) duplicated = bmesh.ops.duplicate(bm, geom=list(faces)) - verts = bm_sort_out_geom(duplicated["geom"])["verts"] + verts = tool.Model.bm_sort_out_geom(duplicated["geom"])["verts"] bmesh.ops.transform(bm, verts=verts, matrix=matrix, space=Matrix.Identity(4)) return verts @@ -242,7 +224,7 @@ def create_bm_extruded_profile( extruded = bmesh.ops.extrude_face_region(bm, geom=new_faces) extrusion_vector = extrusion_vector * magnitude - extruded_verts = bm_sort_out_geom(extruded["geom"])["verts"] + extruded_verts = tool.Model.bm_sort_out_geom(extruded["geom"])["verts"] bmesh.ops.translate(bm, vec=extrusion_vector, verts=extruded_verts) bmesh.ops.translate(bm, vec=position, verts=new_verts + extruded_verts) @@ -304,7 +286,7 @@ def create_bm_door_lining( extruded = bmesh.ops.extrude_face_region(bm, geom=new_faces) extrusion_vector = Vector((0, 1, 0)) * depth - translate_verts = [v for v in extruded["geom"] if isinstance(v, BMVert)] + translate_verts = [v for v in extruded["geom"] if isinstance(v, bmesh.types.BMVert)] bmesh.ops.translate(bm, vec=extrusion_vector, verts=translate_verts) bmesh.ops.translate(bm, vec=position, verts=new_verts + translate_verts) diff --git a/src/bonsai/bonsai/bim/module/model/railing.py b/src/bonsai/bonsai/bim/module/model/railing.py index 1dc6638b5c..edf4eae35d 100644 --- a/src/bonsai/bonsai/bim/module/model/railing.py +++ b/src/bonsai/bonsai/bim/module/model/railing.py @@ -26,7 +26,6 @@ import ifcopenshell.util.unit import bonsai.core.root import bonsai.core.geometry import bonsai.tool as tool -from bonsai.bim.module.model.door import bm_sort_out_geom from bonsai.bim.module.model.data import RailingData, refresh from bonsai.bim.module.model.decorator import ProfileDecorator @@ -47,7 +46,7 @@ def bm_split_edge_at_offset(edge: bmesh.types.BMEdge, offset: float) -> dict[str split_output_0 = bmesh.utils.edge_split(edge, v0, offset / edge_len) split_output_1 = bmesh.utils.edge_split(edge, v1, offset / (edge_len - offset)) - new_geometry = bm_sort_out_geom(split_output_0 + split_output_1) + new_geometry = tool.Model.bm_sort_out_geom(split_output_0 + split_output_1) return new_geometry @@ -175,11 +174,11 @@ def update_railing_modifier_bmesh(context: bpy.types.Context) -> None: ortho_vector = edge_dir.cross(V_(0, 0, 1)) extruded_geom = bmesh.ops.extrude_edge_only(bm, edges=[main_edge])["geom"] - extruded_verts = bm_sort_out_geom(extruded_geom)["verts"] + extruded_verts = tool.Model.bm_sort_out_geom(extruded_geom)["verts"] bmesh.ops.translate(bm, vec=ortho_vector * (-thickness / 2), verts=extruded_verts) extruded_geom = bmesh.ops.extrude_edge_only(bm, edges=[main_edge])["geom"] - extruded_verts = bm_sort_out_geom(extruded_geom)["verts"] + extruded_verts = tool.Model.bm_sort_out_geom(extruded_geom)["verts"] bmesh.ops.translate(bm, vec=ortho_vector * (thickness / 2), verts=extruded_verts) # dissolve middle edge @@ -187,7 +186,7 @@ def update_railing_modifier_bmesh(context: bpy.types.Context) -> None: # height extruded_geom = bmesh.ops.extrude_face_region(bm, geom=bm.faces)["geom"] - extruded_verts = bm_sort_out_geom(extruded_geom)["verts"] + extruded_verts = tool.Model.bm_sort_out_geom(extruded_geom)["verts"] extrusion_vector = Vector((0, 0, 1)) * height bmesh.ops.translate(bm, vec=extrusion_vector, verts=extruded_verts) diff --git a/src/bonsai/bonsai/bim/module/model/roof.py b/src/bonsai/bonsai/bim/module/model/roof.py index e60fdc65a7..d31a251c94 100644 --- a/src/bonsai/bonsai/bim/module/model/roof.py +++ b/src/bonsai/bonsai/bim/module/model/roof.py @@ -26,7 +26,6 @@ import ifcopenshell.util.unit import bonsai.core.root import bonsai.tool as tool from bonsai.bim.helper import convert_property_group_from_si -from bonsai.bim.module.model.door import bm_sort_out_geom from bonsai.bim.module.model.data import RoofData, refresh from bonsai.bim.module.model.decorator import ProfileDecorator @@ -327,7 +326,7 @@ def generate_hiped_roof_bmesh( bmesh.ops.delete(bm, geom=bottom_chords_to_remove, context="EDGES") # add roof thickness - extrusion_geom = bm_sort_out_geom(bmesh.ops.extrude_face_region(bm, geom=bm.faces)["geom"]) + extrusion_geom = tool.Model.bm_sort_out_geom(bmesh.ops.extrude_face_region(bm, geom=bm.faces)["geom"]) extruded_edges = extrusion_geom["edges"] extruded_verts = extrusion_geom["verts"] rafter_edge_angle = pi / 2 - rafter_edge_angle diff --git a/src/bonsai/bonsai/tool/model.py b/src/bonsai/bonsai/tool/model.py index e69531cce4..da720b755e 100644 --- a/src/bonsai/bonsai/tool/model.py +++ b/src/bonsai/bonsai/tool/model.py @@ -1263,10 +1263,12 @@ class Model(bonsai.core.tool.Model): if stair_type == "WOOD/STEEL": builder = ShapeBuilder(None) + # full tread rectangle def get_tread_verts(*args, **kwargs): fn = partial(builder.get_rectangle_coords, position=V_(0, -(tread_depth - tread_rise))) return [Vector(x) for x in fn(*args, **kwargs)] + default_tread_verts = get_tread_verts(size=V_(tread_run + nosing_overlap, tread_depth)) default_tread_offset = V_(tread_run + nosing_tread_gap, tread_rise) @@ -2011,3 +2013,18 @@ class Model(bonsai.core.tool.Model): @classmethod def get_booleaned_obj(cls, boolean_obj: bpy.types.Object) -> bpy.types.Object: return boolean_obj.data.BIMMeshProperties.obj + + @classmethod + def bm_sort_out_geom( + cls, geom_data: list[Union[bmesh.types.BMVert, bmesh.types.BMEdge, bmesh.types.BMFace]] + ) -> dict[str, Any]: + geom_dict = {"verts": [], "edges": [], "faces": []} + + for el in geom_data: + if isinstance(el, bmesh.types.BMVert): + geom_dict["verts"].append(el) + elif isinstance(el, bmesh.types.BMFace): + geom_dict["faces"].append(el) + else: + geom_dict["edges"].append(el) + return geom_dict