mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-09 13:52:23 +00:00
You can now add new mesh representation items
This commit is contained in:
@@ -20,6 +20,7 @@ import bpy
|
|||||||
from . import ui, prop, operator
|
from . import ui, prop, operator
|
||||||
|
|
||||||
classes = (
|
classes = (
|
||||||
|
operator.AddMeshlikeItem,
|
||||||
operator.AddRepresentation,
|
operator.AddRepresentation,
|
||||||
operator.CopyRepresentation,
|
operator.CopyRepresentation,
|
||||||
operator.DisableEditingRepresentationItemShapeAspect,
|
operator.DisableEditingRepresentationItemShapeAspect,
|
||||||
|
|||||||
@@ -1742,6 +1742,93 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
should_save: bpy.props.BoolProperty(name="Should Save", default=True)
|
should_save: bpy.props.BoolProperty(name="Should Save", default=True)
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
return IfcStore.execute_ifc_operator(self, context, is_invoke=True)
|
||||||
|
|
||||||
|
def _invoke(self, context, event):
|
||||||
|
if not context.active_object:
|
||||||
|
return {"FINISHED"}
|
||||||
|
self.is_valid = True
|
||||||
|
|
||||||
|
if context.mode != "OBJECT":
|
||||||
|
bpy.ops.object.mode_set(mode="OBJECT")
|
||||||
|
|
||||||
|
if not tool.Ifc.get():
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
context.scene.BIMGeometryProperties.is_changing_mode = True
|
||||||
|
if context.scene.BIMGeometryProperties.representation_obj:
|
||||||
|
if context.scene.BIMGeometryProperties.mode != "ITEM":
|
||||||
|
context.scene.BIMGeometryProperties.mode = "ITEM"
|
||||||
|
else:
|
||||||
|
if context.scene.BIMGeometryProperties.mode != "OBJECT":
|
||||||
|
context.scene.BIMGeometryProperties.mode = "OBJECT"
|
||||||
|
context.scene.BIMGeometryProperties.is_changing_mode = False
|
||||||
|
|
||||||
|
if context.active_object:
|
||||||
|
element = tool.Ifc.get_entity(context.active_object)
|
||||||
|
if element and element.is_a("IfcRelSpaceBoundary"):
|
||||||
|
return bpy.ops.bim.edit_boundary_geometry()
|
||||||
|
elif tool.Geometry.is_representation_item(context.active_object):
|
||||||
|
self.edit_representation_item(context.active_object)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
objs = context.selected_objects or [context.active_object]
|
||||||
|
print("objs are", objs)
|
||||||
|
|
||||||
|
self.edited_objs = []
|
||||||
|
self.unchanged_objs_with_openings = []
|
||||||
|
|
||||||
|
for obj in objs:
|
||||||
|
if not obj:
|
||||||
|
continue
|
||||||
|
|
||||||
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
if not element:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if tool.Profile.is_editing_profile():
|
||||||
|
profile_id = context.scene.BIMProfileProperties.active_profile_id
|
||||||
|
if profile_id:
|
||||||
|
profile = tool.Ifc.get().by_id(profile_id)
|
||||||
|
if tool.Ifc.get_object(profile): # We are editing an arbitrary profile
|
||||||
|
bpy.ops.bim.edit_arbitrary_profile()
|
||||||
|
elif tool.Blender.Modifier.is_railing(element):
|
||||||
|
bpy.ops.bim.finish_editing_railing_path()
|
||||||
|
elif tool.Blender.Modifier.is_roof(element):
|
||||||
|
bpy.ops.bim.finish_editing_roof_path()
|
||||||
|
elif tool.Model.get_usage_type(element) == "PROFILE":
|
||||||
|
bpy.ops.bim.edit_extrusion_axis()
|
||||||
|
# if in the process of editing arbitrary profile
|
||||||
|
elif context.scene.BIMProfileProperties.active_arbitrary_profile_id:
|
||||||
|
bpy.ops.bim.edit_arbitrary_profile()
|
||||||
|
else:
|
||||||
|
bpy.ops.bim.edit_extrusion_profile()
|
||||||
|
return self.execute(context)
|
||||||
|
elif obj.data.BIMMeshProperties.ifc_definition_id:
|
||||||
|
if not tool.Geometry.has_geometric_data(obj):
|
||||||
|
self.is_valid = False
|
||||||
|
self.should_save = False
|
||||||
|
representation = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
||||||
|
if tool.Geometry.is_meshlike(
|
||||||
|
representation
|
||||||
|
) and obj.data.BIMMeshProperties.mesh_checksum != tool.Geometry.get_mesh_checksum(obj.data):
|
||||||
|
self.edited_objs.append(obj)
|
||||||
|
elif getattr(element, "HasOpenings", None):
|
||||||
|
self.unchanged_objs_with_openings.append(obj)
|
||||||
|
else:
|
||||||
|
tool.Ifc.finish_edit(obj)
|
||||||
|
elif element.is_a("IfcGridAxis"):
|
||||||
|
if not tool.Geometry.has_geometric_data(obj):
|
||||||
|
self.is_valid = False
|
||||||
|
self.should_save = False
|
||||||
|
if obj.data.BIMMeshProperties.mesh_checksum != tool.Geometry.get_mesh_checksum(obj.data):
|
||||||
|
self.edited_objs.append(obj)
|
||||||
|
else:
|
||||||
|
tool.Ifc.finish_edit(obj)
|
||||||
|
|
||||||
|
return self.execute(context)
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
if not context.active_object:
|
if not context.active_object:
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -1866,91 +1953,6 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
context.scene.BIMGeometryProperties.mode = "EDIT"
|
context.scene.BIMGeometryProperties.mode = "EDIT"
|
||||||
context.scene.BIMGeometryProperties.is_changing_mode = False
|
context.scene.BIMGeometryProperties.is_changing_mode = False
|
||||||
|
|
||||||
def invoke(self, context, event):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context, is_invoke=True)
|
|
||||||
|
|
||||||
def _invoke(self, context, event):
|
|
||||||
if not context.active_object:
|
|
||||||
return {"FINISHED"}
|
|
||||||
self.is_valid = True
|
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode="EDIT", toggle=True)
|
|
||||||
|
|
||||||
context.scene.BIMGeometryProperties.is_changing_mode = True
|
|
||||||
if context.scene.BIMGeometryProperties.representation_obj:
|
|
||||||
if context.scene.BIMGeometryProperties.mode != "ITEM":
|
|
||||||
context.scene.BIMGeometryProperties.mode = "ITEM"
|
|
||||||
else:
|
|
||||||
if context.scene.BIMGeometryProperties.mode != "OBJECT":
|
|
||||||
context.scene.BIMGeometryProperties.mode = "OBJECT"
|
|
||||||
context.scene.BIMGeometryProperties.is_changing_mode = False
|
|
||||||
|
|
||||||
if not tool.Ifc.get():
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
if context.active_object:
|
|
||||||
element = tool.Ifc.get_entity(context.active_object)
|
|
||||||
if element and element.is_a("IfcRelSpaceBoundary"):
|
|
||||||
return bpy.ops.bim.edit_boundary_geometry()
|
|
||||||
elif tool.Geometry.is_representation_item(context.active_object):
|
|
||||||
self.edit_representation_item(context.active_object)
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
objs = context.selected_objects or [context.active_object]
|
|
||||||
|
|
||||||
self.edited_objs = []
|
|
||||||
self.unchanged_objs_with_openings = []
|
|
||||||
|
|
||||||
for obj in objs:
|
|
||||||
if not obj:
|
|
||||||
continue
|
|
||||||
|
|
||||||
element = tool.Ifc.get_entity(obj)
|
|
||||||
if not element:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if tool.Profile.is_editing_profile():
|
|
||||||
profile_id = context.scene.BIMProfileProperties.active_profile_id
|
|
||||||
if profile_id:
|
|
||||||
profile = tool.Ifc.get().by_id(profile_id)
|
|
||||||
if tool.Ifc.get_object(profile): # We are editing an arbitrary profile
|
|
||||||
bpy.ops.bim.edit_arbitrary_profile()
|
|
||||||
elif tool.Blender.Modifier.is_railing(element):
|
|
||||||
bpy.ops.bim.finish_editing_railing_path()
|
|
||||||
elif tool.Blender.Modifier.is_roof(element):
|
|
||||||
bpy.ops.bim.finish_editing_roof_path()
|
|
||||||
elif tool.Model.get_usage_type(element) == "PROFILE":
|
|
||||||
bpy.ops.bim.edit_extrusion_axis()
|
|
||||||
# if in the process of editing arbitrary profile
|
|
||||||
elif context.scene.BIMProfileProperties.active_arbitrary_profile_id:
|
|
||||||
bpy.ops.bim.edit_arbitrary_profile()
|
|
||||||
else:
|
|
||||||
bpy.ops.bim.edit_extrusion_profile()
|
|
||||||
return self.execute(context)
|
|
||||||
elif obj.data.BIMMeshProperties.ifc_definition_id:
|
|
||||||
if not tool.Geometry.has_geometric_data(obj):
|
|
||||||
self.is_valid = False
|
|
||||||
self.should_save = False
|
|
||||||
representation = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
|
||||||
if tool.Geometry.is_meshlike(
|
|
||||||
representation
|
|
||||||
) and obj.data.BIMMeshProperties.mesh_checksum != tool.Geometry.get_mesh_checksum(obj.data):
|
|
||||||
self.edited_objs.append(obj)
|
|
||||||
elif getattr(element, "HasOpenings", None):
|
|
||||||
self.unchanged_objs_with_openings.append(obj)
|
|
||||||
else:
|
|
||||||
tool.Ifc.finish_edit(obj)
|
|
||||||
elif element.is_a("IfcGridAxis"):
|
|
||||||
if not tool.Geometry.has_geometric_data(obj):
|
|
||||||
self.is_valid = False
|
|
||||||
self.should_save = False
|
|
||||||
if obj.data.BIMMeshProperties.mesh_checksum != tool.Geometry.get_mesh_checksum(obj.data):
|
|
||||||
self.edited_objs.append(obj)
|
|
||||||
else:
|
|
||||||
tool.Ifc.finish_edit(obj)
|
|
||||||
|
|
||||||
return self.execute(context)
|
|
||||||
|
|
||||||
|
|
||||||
class FlipObject(bpy.types.Operator):
|
class FlipObject(bpy.types.Operator):
|
||||||
bl_idname = "bim.flip_object"
|
bl_idname = "bim.flip_object"
|
||||||
@@ -2409,3 +2411,63 @@ class UpdateItemAttributes(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
item.Depth = attribute.float_value
|
item.Depth = attribute.float_value
|
||||||
tool.Geometry.reload_representation(bpy.context.scene.BIMGeometryProperties.representation_obj)
|
tool.Geometry.reload_representation(bpy.context.scene.BIMGeometryProperties.representation_obj)
|
||||||
tool.Geometry.import_item(obj)
|
tool.Geometry.import_item(obj)
|
||||||
|
|
||||||
|
|
||||||
|
class AddMeshlikeItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
|
bl_idname = "bim.add_meshlike_item"
|
||||||
|
bl_label = "Add Meshlike Item"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
shape: bpy.props.StringProperty(name="Shape")
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
props = context.scene.BIMGeometryProperties
|
||||||
|
mesh = bpy.data.meshes.new("Tmp")
|
||||||
|
obj = bpy.data.objects.new("Tmp", mesh)
|
||||||
|
scene = bpy.context.scene
|
||||||
|
scene.collection.objects.link(obj)
|
||||||
|
bpy.context.view_layer.objects.active = obj
|
||||||
|
obj.select_set(True)
|
||||||
|
bm = bmesh.new()
|
||||||
|
matrix = props.representation_obj.matrix_world.copy()
|
||||||
|
matrix.translation = context.scene.cursor.location
|
||||||
|
matrix = props.representation_obj.matrix_world.inverted() @ matrix
|
||||||
|
if self.shape == "CUBE":
|
||||||
|
bmesh.ops.create_cube(bm, matrix=matrix, size=0.5)
|
||||||
|
elif self.shape == "PLANE":
|
||||||
|
bmesh.ops.create_grid(bm, matrix=matrix, size=0.5)
|
||||||
|
elif self.shape == "CIRCLE":
|
||||||
|
bmesh.ops.create_circle(bm, matrix=matrix, radius=0.25, segments=16, cap_ends=True)
|
||||||
|
elif self.shape == "UVSPHERE":
|
||||||
|
bmesh.ops.create_uvsphere(bm, matrix=matrix, radius=0.25, u_segments=16, v_segments=16)
|
||||||
|
elif self.shape == "ICOSPHERE":
|
||||||
|
bmesh.ops.create_icosphere(bm, matrix=matrix, radius=0.25, subdivisions=2)
|
||||||
|
elif self.shape == "CYLINDER":
|
||||||
|
# Cone is legitimate.
|
||||||
|
bmesh.ops.create_cone(bm, matrix=matrix, radius1=0.25, radius2=0.25, depth=0.5, segments=16, cap_ends=True)
|
||||||
|
|
||||||
|
bm.to_mesh(mesh)
|
||||||
|
bm.free()
|
||||||
|
mesh.update()
|
||||||
|
obj.matrix_world = props.representation_obj.matrix_world
|
||||||
|
new = props.item_objs.add()
|
||||||
|
new.obj = obj
|
||||||
|
|
||||||
|
tool.Geometry.lock_object(obj)
|
||||||
|
|
||||||
|
builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get())
|
||||||
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
|
verts = [v.co / unit_scale for v in obj.data.vertices]
|
||||||
|
faces = [p.vertices[:] for p in obj.data.polygons]
|
||||||
|
|
||||||
|
representation = tool.Geometry.get_active_representation(props.representation_obj)
|
||||||
|
representation = ifcopenshell.util.representation.resolve_representation(representation)
|
||||||
|
|
||||||
|
if representation.RepresentationType in ("Brep", "AdvancedBrep"):
|
||||||
|
item = builder.faceted_brep(verts, faces)
|
||||||
|
elif representation.RepresentationType in ("Tessellation"):
|
||||||
|
item = builder.mesh(verts, faces)
|
||||||
|
|
||||||
|
representation.Items = list(representation.Items) + [item]
|
||||||
|
tool.Geometry.reload_representation(bpy.context.scene.BIMGeometryProperties.representation_obj)
|
||||||
|
obj.name = obj.data.name = f"Item/{item.is_a()}/{item.id()}"
|
||||||
|
obj.data.BIMMeshProperties.ifc_definition_id = item.id()
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ classes = (
|
|||||||
product.LoadTypeThumbnails,
|
product.LoadTypeThumbnails,
|
||||||
product.MirrorElements,
|
product.MirrorElements,
|
||||||
workspace.Hotkey,
|
workspace.Hotkey,
|
||||||
|
workspace.BIM_MT_add_meshlike_item,
|
||||||
wall.AlignWall,
|
wall.AlignWall,
|
||||||
wall.ChangeExtrusionDepth,
|
wall.ChangeExtrusionDepth,
|
||||||
wall.ChangeExtrusionXAngle,
|
wall.ChangeExtrusionXAngle,
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ from natsort import natsorted
|
|||||||
|
|
||||||
def refresh():
|
def refresh():
|
||||||
AuthoringData.is_loaded = False
|
AuthoringData.is_loaded = False
|
||||||
|
ItemData.is_loaded = False
|
||||||
ArrayData.is_loaded = False
|
ArrayData.is_loaded = False
|
||||||
StairData.is_loaded = False
|
StairData.is_loaded = False
|
||||||
SverchokData.is_loaded = False
|
SverchokData.is_loaded = False
|
||||||
@@ -620,3 +621,27 @@ class RoofData:
|
|||||||
|
|
||||||
general_params[prop_readable_name] = prop_value
|
general_params[prop_readable_name] = prop_value
|
||||||
return general_params
|
return general_params
|
||||||
|
|
||||||
|
|
||||||
|
class ItemData:
|
||||||
|
data = {}
|
||||||
|
is_loaded = False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls):
|
||||||
|
cls.is_loaded = True
|
||||||
|
cls.data = {}
|
||||||
|
cls.data["representation_identifier"] = cls.representation_identifier()
|
||||||
|
cls.data["representation_type"] = cls.representation_type()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def representation_identifier(cls):
|
||||||
|
props = bpy.context.scene.BIMGeometryProperties
|
||||||
|
rep = tool.Geometry.get_active_representation(props.representation_obj)
|
||||||
|
return rep.RepresentationIdentifier
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def representation_type(cls):
|
||||||
|
props = bpy.context.scene.BIMGeometryProperties
|
||||||
|
rep = tool.Geometry.get_active_representation(props.representation_obj)
|
||||||
|
return rep.RepresentationType
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ import bonsai.tool as tool
|
|||||||
import bonsai.core.model as core
|
import bonsai.core.model as core
|
||||||
from bonsai.bim.module.model.wall import DumbWallJoiner
|
from bonsai.bim.module.model.wall import DumbWallJoiner
|
||||||
from bonsai.bim.helper import prop_with_search
|
from bonsai.bim.helper import prop_with_search
|
||||||
from bpy.types import WorkSpaceTool
|
from bpy.types import WorkSpaceTool, Menu
|
||||||
from bonsai.bim.module.model.data import AuthoringData
|
from bonsai.bim.module.model.data import AuthoringData, ItemData
|
||||||
from bonsai.bim.module.system.data import PortData
|
from bonsai.bim.module.system.data import PortData
|
||||||
from bonsai.bim.module.model.prop import get_ifc_class
|
from bonsai.bim.module.model.prop import get_ifc_class
|
||||||
|
|
||||||
@@ -262,9 +262,17 @@ def format_ifc_camel_case(string):
|
|||||||
class EditItemUI:
|
class EditItemUI:
|
||||||
@classmethod
|
@classmethod
|
||||||
def draw(cls, context, layout):
|
def draw(cls, context, layout):
|
||||||
|
if not ItemData.is_loaded:
|
||||||
|
ItemData.load()
|
||||||
|
|
||||||
cls.layout = layout
|
cls.layout = layout
|
||||||
row = cls.layout.row()
|
row = cls.layout.row()
|
||||||
row.label(text="Item Mode", icon="MESH_DATA")
|
row.label(text="Item Mode", icon="MESH_DATA")
|
||||||
|
row = cls.layout.row()
|
||||||
|
row.label(text="Context: " + ItemData.data["representation_identifier"], icon="SCENE_DATA")
|
||||||
|
row = cls.layout.row()
|
||||||
|
row.label(text="Type: " + ItemData.data["representation_type"], icon="OUTLINER_OB_MESH")
|
||||||
|
cls.layout.menu("BIM_MT_add_meshlike_item", icon="ADD")
|
||||||
if not (obj := context.active_object) or not tool.Geometry.is_representation_item(obj):
|
if not (obj := context.active_object) or not tool.Geometry.is_representation_item(obj):
|
||||||
return
|
return
|
||||||
for item_attribute in obj.data.BIMMeshProperties.item_attributes:
|
for item_attribute in obj.data.BIMMeshProperties.item_attributes:
|
||||||
@@ -275,6 +283,19 @@ class EditItemUI:
|
|||||||
row.operator("bim.update_item_attributes", icon="FILE_REFRESH", text="")
|
row.operator("bim.update_item_attributes", icon="FILE_REFRESH", text="")
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_MT_add_meshlike_item(Menu):
|
||||||
|
bl_idname = "BIM_MT_add_meshlike_item"
|
||||||
|
bl_label = "Add Item"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
self.layout.operator("bim.add_meshlike_item", icon="MESH_PLANE", text="Mesh Plane").shape = "PLANE"
|
||||||
|
self.layout.operator("bim.add_meshlike_item", icon="MESH_CUBE", text="Mesh Cube").shape = "CUBE"
|
||||||
|
self.layout.operator("bim.add_meshlike_item", icon="MESH_CIRCLE", text="Mesh Circle").shape = "CIRCLE"
|
||||||
|
self.layout.operator("bim.add_meshlike_item", icon="MESH_UVSPHERE", text="Mesh UV Sphere").shape = "UVSPHERE"
|
||||||
|
self.layout.operator("bim.add_meshlike_item", icon="MESH_ICOSPHERE", text="Mesh Icosphere").shape = "ICOSPHERE"
|
||||||
|
self.layout.operator("bim.add_meshlike_item", icon="MESH_CYLINDER", text="Mesh Cylinder").shape = "CYLINDER"
|
||||||
|
|
||||||
|
|
||||||
class CreateObjectUI:
|
class CreateObjectUI:
|
||||||
@classmethod
|
@classmethod
|
||||||
def draw(cls, context, layout, ifc_element_type=None):
|
def draw(cls, context, layout, ifc_element_type=None):
|
||||||
|
|||||||
@@ -1422,21 +1422,22 @@ class Geometry(bonsai.core.tool.Geometry):
|
|||||||
has_changed = False
|
has_changed = False
|
||||||
for item_obj in props.item_objs:
|
for item_obj in props.item_objs:
|
||||||
obj = item_obj.obj
|
obj = item_obj.obj
|
||||||
if not tool.Ifc.is_moved(obj):
|
|
||||||
continue
|
|
||||||
has_changed = True
|
|
||||||
item = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
item = tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
||||||
old_position = item.Position
|
if item.is_a("IfcSweptAreaSolid"):
|
||||||
if np.allclose(np.array(obj.matrix_world), np.array(rep_obj.matrix_world), atol=1e-4):
|
if not tool.Ifc.is_moved(obj):
|
||||||
|
continue
|
||||||
|
has_changed = True
|
||||||
|
old_position = item.Position
|
||||||
|
if np.allclose(np.array(obj.matrix_world), np.array(rep_obj.matrix_world), atol=1e-4):
|
||||||
|
if old_position:
|
||||||
|
item.Position = None
|
||||||
|
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_position)
|
||||||
|
continue
|
||||||
|
rel_matrix = rep_matrix_i @ obj.matrix_world
|
||||||
|
rel_matrix.translation /= unit_scale
|
||||||
|
item.Position = builder.create_axis2_placement_3d_from_matrix(np.array(rel_matrix))
|
||||||
if old_position:
|
if old_position:
|
||||||
item.Position = None
|
|
||||||
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_position)
|
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_position)
|
||||||
continue
|
|
||||||
rel_matrix = rep_matrix_i @ obj.matrix_world
|
|
||||||
rel_matrix.translation /= unit_scale
|
|
||||||
item.Position = builder.create_axis2_placement_3d_from_matrix(np.array(rel_matrix))
|
|
||||||
if old_position:
|
|
||||||
ifcopenshell.util.element.remove_deep2(tool.Ifc.get(), old_position)
|
|
||||||
if has_changed:
|
if has_changed:
|
||||||
cls.reload_representation(rep_obj)
|
cls.reload_representation(rep_obj)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user