This commit is contained in:
Andrej730
2025-04-04 11:54:56 +05:00
parent c0e8c3d1b5
commit 6676c7f62e
4 changed files with 40 additions and 17 deletions
+8 -7
View File
@@ -24,10 +24,12 @@ import math
import numpy as np import numpy as np
import ifcopenshell import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.geometry
import ifcopenshell.util.unit import ifcopenshell.util.unit
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.placement import ifcopenshell.util.placement
import ifcopenshell.util.representation import ifcopenshell.util.representation
import ifcopenshell.util.shape_builder
import ifcopenshell.util.type import ifcopenshell.util.type
import mathutils.geometry import mathutils.geometry
import bonsai.core.type import bonsai.core.type
@@ -66,7 +68,7 @@ class ExtendWallsToUnderside(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context): def _execute(self, context):
slab = None slab = None
walls = [] walls: list[bpy.types.Object] = []
if (obj := tool.Blender.get_active_object(is_selected=True)) and (element := tool.Ifc.get_entity(obj)): if (obj := tool.Blender.get_active_object(is_selected=True)) and (element := tool.Ifc.get_entity(obj)):
slab = obj slab = obj
for obj in tool.Blender.get_selected_objects(include_active=False): for obj in tool.Blender.get_selected_objects(include_active=False):
@@ -1192,14 +1194,14 @@ class DumbWallJoiner:
self.set_axis(element1, intersect, p2) self.set_axis(element1, intersect, p2)
self.recreate_wall(element1, wall1) self.recreate_wall(element1, wall1)
def set_length(self, wall1, si_length): def set_length(self, wall1: bpy.types.Object, si_length: float) -> None:
element1 = tool.Ifc.get_entity(wall1) element1 = tool.Ifc.get_entity(wall1)
if not element1: if not element1:
return return
if tool.Ifc.is_moved(wall1): if tool.Ifc.is_moved(wall1):
bonsai.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=wall1) bonsai.core.geometry.edit_object_placement(tool.Ifc, tool.Geometry, tool.Surveyor, obj=wall1)
ifcopenshell.api.run("geometry.disconnect_path", tool.Ifc.get(), element=element1, connection_type="ATEND") ifcopenshell.api.geometry.disconnect_path(tool.Ifc.get(), element=element1, connection_type="ATEND")
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
p1, p2 = ifcopenshell.util.representation.get_reference_line(element1) p1, p2 = ifcopenshell.util.representation.get_reference_line(element1)
@@ -1207,7 +1209,7 @@ class DumbWallJoiner:
self.set_axis(element1, p1, p2) self.set_axis(element1, p1, p2)
self.recreate_wall(element1, wall1) self.recreate_wall(element1, wall1)
def join_T(self, wall1, wall2): def join_T(self, wall1: bpy.types.Object, wall2: bpy.types.Object) -> None:
element1 = tool.Ifc.get_entity(wall1) element1 = tool.Ifc.get_entity(wall1)
element2 = tool.Ifc.get_entity(wall2) element2 = tool.Ifc.get_entity(wall2)
axis1 = tool.Model.get_wall_axis(wall1) axis1 = tool.Model.get_wall_axis(wall1)
@@ -1219,8 +1221,7 @@ class DumbWallJoiner:
return return
connection = "ATEND" if tool.Cad.edge_percent(intersect, axis1["reference"]) > 0.5 else "ATSTART" connection = "ATEND" if tool.Cad.edge_percent(intersect, axis1["reference"]) > 0.5 else "ATSTART"
ifcopenshell.api.run( ifcopenshell.api.geometry.connect_path(
"geometry.connect_path",
tool.Ifc.get(), tool.Ifc.get(),
related_element=element1, related_element=element1,
relating_element=element2, relating_element=element2,
@@ -1231,7 +1232,7 @@ class DumbWallJoiner:
self.recreate_wall(element1, wall1, axis1["reference"], axis1["reference"]) self.recreate_wall(element1, wall1, axis1["reference"], axis1["reference"])
def connect(self, obj1, obj2): def connect(self, obj1: bpy.types.Object, obj2: bpy.types.Object) -> None:
wall1 = tool.Ifc.get_entity(obj1) wall1 = tool.Ifc.get_entity(obj1)
wall2 = tool.Ifc.get_entity(obj2) wall2 = tool.Ifc.get_entity(obj2)
if tool.Ifc.is_moved(obj1): if tool.Ifc.is_moved(obj1):
+28 -7
View File
@@ -16,11 +16,21 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bonsai.core.tool as tool from __future__ import annotations
from typing import Literal, Iterable from typing import TYPE_CHECKING, Optional, Literal, Iterable
if TYPE_CHECKING:
import bpy
import ifcopenshell
import bonsai.tool as tool
from mathutils import Vector
from bonsai.bim.module.model.wall import DumbWallJoiner
def unjoin_walls(ifc: tool.Ifc, blender: tool.Blender, geometry: tool.Geometry, joiner, model: tool.Model) -> None: def unjoin_walls(
ifc: tool.Ifc, blender: tool.Blender, geometry: tool.Geometry, joiner: DumbWallJoiner, model: tool.Model
) -> None:
for obj in blender.get_selected_objects(): for obj in blender.get_selected_objects():
if not (element := ifc.get_entity(obj)) or model.get_usage_type(element) != "LAYER2": if not (element := ifc.get_entity(obj)) or model.get_usage_type(element) != "LAYER2":
continue continue
@@ -31,7 +41,12 @@ def unjoin_walls(ifc: tool.Ifc, blender: tool.Blender, geometry: tool.Geometry,
def extend_walls( def extend_walls(
ifc: tool.Ifc, blender: tool.Blender, geometry: tool.Geometry, joiner, model: tool.Model, target ifc: tool.Ifc,
blender: tool.Blender,
geometry: tool.Geometry,
joiner: DumbWallJoiner,
model: tool.Model,
target: Vector,
) -> None: ) -> None:
for obj in blender.get_selected_objects(): for obj in blender.get_selected_objects():
if not (element := ifc.get_entity(obj)) or model.get_usage_type(element) != "LAYER2": if not (element := ifc.get_entity(obj)) or model.get_usage_type(element) != "LAYER2":
@@ -44,7 +59,7 @@ def join_walls_LV(
ifc: tool.Ifc, ifc: tool.Ifc,
blender: tool.Blender, blender: tool.Blender,
geometry: tool.Geometry, geometry: tool.Geometry,
joiner, joiner: DumbWallJoiner,
model: tool.Model, model: tool.Model,
join_type: Literal["L", "V"] = "L", join_type: Literal["L", "V"] = "L",
) -> None: ) -> None:
@@ -66,7 +81,11 @@ def join_walls_LV(
def extend_wall_to_slab( def extend_wall_to_slab(
ifc: tool.Ifc, geometry: tool.Geometry, model: tool.Model, slab_obj, wall_objs: Iterable ifc: tool.Ifc,
geometry: tool.Geometry,
model: tool.Model,
slab_obj: bpy.types.Object,
wall_objs: list[bpy.types.Object],
) -> None: ) -> None:
if not (clip := model.get_slab_clipping_bmesh(slab_obj)): if not (clip := model.get_slab_clipping_bmesh(slab_obj)):
return # Nothing to clip? return # Nothing to clip?
@@ -80,7 +99,9 @@ def extend_wall_to_slab(
model.reload_body_representation(wall_objs) model.reload_body_representation(wall_objs)
def join_walls_TZ(ifc: tool.Ifc, blender: tool.Blender, geometry: tool.Geometry, joiner, model: tool.Model) -> None: def join_walls_TZ(
ifc: tool.Ifc, blender: tool.Blender, geometry: tool.Geometry, joiner: DumbWallJoiner, model: tool.Model
) -> None:
selected_objs = [ selected_objs = [
o o
for o in blender.get_selected_objects() for o in blender.get_selected_objects()
+1 -1
View File
@@ -64,7 +64,7 @@ class Debug(bonsai.core.tool.Debug):
pass pass
@classmethod @classmethod
def debug_bmesh(cls, bm: bpy.types.BMesh, name: str = "Debug") -> bpy.types.Object: def debug_bmesh(cls, bm: bmesh.types.BMesh, name: str = "Debug") -> bpy.types.Object:
mesh = bpy.data.meshes.new("Debug") mesh = bpy.data.meshes.new("Debug")
bm.to_mesh(mesh) bm.to_mesh(mesh)
obj = bpy.data.objects.new(name, mesh) obj = bpy.data.objects.new(name, mesh)
+3 -2
View File
@@ -34,6 +34,7 @@ import ifcopenshell.util.element
import ifcopenshell.util.placement import ifcopenshell.util.placement
import ifcopenshell.util.representation import ifcopenshell.util.representation
import ifcopenshell.util.shape import ifcopenshell.util.shape
import ifcopenshell.util.shape_builder
import ifcopenshell.util.unit import ifcopenshell.util.unit
import bonsai.core.geometry import bonsai.core.geometry
import bonsai.core.tool import bonsai.core.tool
@@ -2104,7 +2105,7 @@ class Model(bonsai.core.tool.Model):
op.material_id = material_id_int op.material_id = material_id_int
@classmethod @classmethod
def get_slab_clipping_bmesh(cls, obj: bpy.types.Object) -> bpy.types.BMesh | None: def get_slab_clipping_bmesh(cls, obj: bpy.types.Object) -> bmesh.types.BMesh | None:
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
bm = bmesh.new() bm = bmesh.new()
@@ -2136,7 +2137,7 @@ class Model(bonsai.core.tool.Model):
return clipping_bm # clipping_bm is in project units return clipping_bm # clipping_bm is in project units
@classmethod @classmethod
def clip_wall_to_slab(cls, wall: ifcopenshell.entity_instance, clipping_bm: bpy.types.BMesh) -> None: def clip_wall_to_slab(cls, wall: ifcopenshell.entity_instance, clipping_bm: bmesh.types.BMesh) -> None:
matrix_i = np.linalg.inv(ifcopenshell.util.placement.get_local_placement(wall.ObjectPlacement)) matrix_i = np.linalg.inv(ifcopenshell.util.placement.get_local_placement(wall.ObjectPlacement))
bm = clipping_bm.copy() bm = clipping_bm.copy()
bmesh.ops.transform(bm, matrix=Matrix(matrix_i.tolist()), verts=bm.verts) bmesh.ops.transform(bm, matrix=Matrix(matrix_i.tolist()), verts=bm.verts)