This commit is contained in:
Andrej730
2025-02-12 11:43:48 +05:00
parent 3e1710c6fc
commit f39e6ccb54
10 changed files with 50 additions and 34 deletions
@@ -90,20 +90,22 @@ class OverrideMeshSeparate(bpy.types.Operator, tool.Ifc.Operator):
self.report({"INFO"}, f"Separating an {item.is_a()} is not supported") self.report({"INFO"}, f"Separating an {item.is_a()} is not supported")
def add_meshlike_item(self, obj: bpy.types.Object) -> None: def add_meshlike_item(self, obj: bpy.types.Object) -> None:
props = bpy.context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
obj.show_in_front = True obj.show_in_front = True
tool.Geometry.lock_object(obj) tool.Geometry.lock_object(obj)
builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get()) builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get())
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
rep_obj = bpy.context.scene.BIMGeometryProperties.representation_obj rep_obj = props.representation_obj
assert rep_obj
if (coordinate_offset := tool.Geometry.get_cartesian_point_offset(rep_obj)) is not None: if (coordinate_offset := tool.Geometry.get_cartesian_point_offset(rep_obj)) is not None:
verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices] verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices]
else: else:
verts = [v.co / unit_scale for v in obj.data.vertices] verts = [v.co / unit_scale for v in obj.data.vertices]
faces = [p.vertices[:] for p in obj.data.polygons] faces = [p.vertices[:] for p in obj.data.polygons]
representation = tool.Geometry.get_active_representation(props.representation_obj) representation = tool.Geometry.get_active_representation(rep_obj)
assert representation
representation = ifcopenshell.util.representation.resolve_representation(representation) representation = ifcopenshell.util.representation.resolve_representation(representation)
if representation.RepresentationType in ("Brep", "AdvancedBrep"): if representation.RepresentationType in ("Brep", "AdvancedBrep"):
@@ -212,8 +214,8 @@ class AddRepresentation(bpy.types.Operator, tool.Ifc.Operator):
def _execute(self, context): def _execute(self, context):
obj = context.active_object obj = context.active_object
assert obj assert obj
props = context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
oprops = obj.BIMGeometryProperties oprops = tool.Geometry.get_object_geometry_props(obj)
ifc_context = int(oprops.contexts or "0") or None ifc_context = int(oprops.contexts or "0") or None
if not ifc_context: if not ifc_context:
return return
@@ -1661,7 +1663,7 @@ class OverrideJoin(bpy.types.Operator, tool.Ifc.Operator):
return self.join_blender_obj() return self.join_blender_obj()
def join_item(self) -> None: def join_item(self) -> None:
props = bpy.context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
item = tool.Ifc.get().by_id(self.target.data.BIMMeshProperties.ifc_definition_id) item = tool.Ifc.get().by_id(self.target.data.BIMMeshProperties.ifc_definition_id)
if tool.Geometry.is_meshlike_item(item): if tool.Geometry.is_meshlike_item(item):
@@ -1941,7 +1943,8 @@ class OverrideModeSetEdit(bpy.types.Operator, tool.Ifc.Operator):
def handle_single_object(self, context: bpy.types.Context, obj: bpy.types.Object) -> None: def handle_single_object(self, context: bpy.types.Context, obj: bpy.types.Object) -> None:
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
if obj == context.scene.BIMGeometryProperties.representation_obj: props = tool.Geometry.get_geometry_props()
if obj == props.representation_obj:
self.report({"ERROR"}, f"Element '{obj.name}' is in item mode and cannot be edited directly") self.report({"ERROR"}, f"Element '{obj.name}' is in item mode and cannot be edited directly")
elif obj in [o.obj for o in context.scene.BIMAggregateProperties.not_editing_objects]: elif obj in [o.obj for o in context.scene.BIMAggregateProperties.not_editing_objects]:
obj.select_set(False) obj.select_set(False)
@@ -2298,7 +2301,7 @@ class OverrideModeSetObject(bpy.types.Operator, tool.Ifc.Operator):
obj.data.BIMMeshProperties.ifc_definition_id = new.id() obj.data.BIMMeshProperties.ifc_definition_id = new.id()
tool.Geometry.import_item(obj) tool.Geometry.import_item(obj)
props = bpy.context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
for item in additional_curves: for item in additional_curves:
representation = tool.Geometry.get_active_representation(props.representation_obj) representation = tool.Geometry.get_active_representation(props.representation_obj)
representation = ifcopenshell.util.representation.resolve_representation(representation) representation = ifcopenshell.util.representation.resolve_representation(representation)
@@ -2452,7 +2455,8 @@ class SelectRepresentationItem(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
if not context.scene.BIMGeometryProperties.representation_obj: props = tool.Geometry.get_geometry_props()
if not props.representation_obj:
cls.poll_message_set("No object opened in item mode.") cls.poll_message_set("No object opened in item mode.")
return False return False
return True return True
@@ -2462,7 +2466,7 @@ class SelectRepresentationItem(bpy.types.Operator):
item = tool.Ifc.get().by_id(obj.BIMGeometryProperties.active_item.ifc_definition_id) item = tool.Ifc.get().by_id(obj.BIMGeometryProperties.active_item.ifc_definition_id)
item_ids = self.get_nested_item_ids(item) item_ids = self.get_nested_item_ids(item)
props = context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
for item_obj in props.item_objs: for item_obj in props.item_objs:
if item_obj.obj.data.BIMMeshProperties.ifc_definition_id in item_ids: if item_obj.obj.data.BIMMeshProperties.ifc_definition_id in item_ids:
tool.Blender.select_object(item_obj.obj) tool.Blender.select_object(item_obj.obj)
@@ -2889,7 +2893,7 @@ class AddMeshlikeItem(bpy.types.Operator, tool.Ifc.Operator):
shape: bpy.props.StringProperty(name="Shape") shape: bpy.props.StringProperty(name="Shape")
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
mesh = bpy.data.meshes.new("Tmp") mesh = bpy.data.meshes.new("Tmp")
obj = bpy.data.objects.new("Tmp", mesh) obj = bpy.data.objects.new("Tmp", mesh)
scene = bpy.context.scene scene = bpy.context.scene
@@ -2923,7 +2927,7 @@ class AddMeshlikeItem(bpy.types.Operator, tool.Ifc.Operator):
builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get()) builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get())
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
rep_obj = bpy.context.scene.BIMGeometryProperties.representation_obj rep_obj = tool.Geometry.get_geometry_props().representation_obj
if (coordinate_offset := tool.Geometry.get_cartesian_point_offset(rep_obj)) is not None: if (coordinate_offset := tool.Geometry.get_cartesian_point_offset(rep_obj)) is not None:
verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices] verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices]
else: else:
@@ -2953,7 +2957,7 @@ class AddSweptAreaSolidItem(bpy.types.Operator, tool.Ifc.Operator):
shape: bpy.props.StringProperty(name="Shape") shape: bpy.props.StringProperty(name="Shape")
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
mesh = bpy.data.meshes.new("Tmp") mesh = bpy.data.meshes.new("Tmp")
obj = bpy.data.objects.new("Tmp", mesh) obj = bpy.data.objects.new("Tmp", mesh)
scene = bpy.context.scene scene = bpy.context.scene
@@ -3009,7 +3013,7 @@ class AddCurvelikeItem(bpy.types.Operator, tool.Ifc.Operator):
shape: CurveShape shape: CurveShape
def _execute(self, context): def _execute(self, context):
props = context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
representation = tool.Geometry.get_active_representation(props.representation_obj) representation = tool.Geometry.get_active_representation(props.representation_obj)
is_2d = representation.ContextOfItems.ContextType == "Plan" is_2d = representation.ContextOfItems.ContextType == "Plan"
@@ -3082,7 +3086,7 @@ class AddHalfSpaceSolidItem(bpy.types.Operator, tool.Ifc.Operator):
self.report({"ERROR"}, "Select an item to apply the half space solid to.") self.report({"ERROR"}, "Select an item to apply the half space solid to.")
return {"CANCELLED"} return {"CANCELLED"}
props = context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
mesh = bpy.data.meshes.new("Tmp") mesh = bpy.data.meshes.new("Tmp")
obj = bpy.data.objects.new("Tmp", mesh) obj = bpy.data.objects.new("Tmp", mesh)
scene = bpy.context.scene scene = bpy.context.scene
+4 -2
View File
@@ -224,7 +224,9 @@ class BIM_PT_representation_items(Panel):
if not RepresentationItemsData.is_loaded: if not RepresentationItemsData.is_loaded:
RepresentationItemsData.load() RepresentationItemsData.load()
obj = context.scene.BIMGeometryProperties.representation_obj or tool.Blender.get_active_object() props = tool.Geometry.get_geometry_props()
obj = props.representation_obj or tool.Blender.get_active_object()
assert obj
props = tool.Geometry.get_object_geometry_props(obj) props = tool.Geometry.get_object_geometry_props(obj)
row = self.layout.row(align=True) row = self.layout.row(align=True)
@@ -576,7 +578,7 @@ class BIM_PT_workarounds(Panel):
) )
def draw(self, context): def draw(self, context):
props = context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
row = self.layout.row() row = self.layout.row()
row.prop(props, "should_force_faceted_brep") row.prop(props, "should_force_faceted_brep")
row = self.layout.row() row = self.layout.row()
+3 -3
View File
@@ -662,19 +662,19 @@ class ItemData:
@classmethod @classmethod
def representation_identifier(cls): def representation_identifier(cls):
props = bpy.context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
rep = tool.Geometry.get_active_representation(props.representation_obj) rep = tool.Geometry.get_active_representation(props.representation_obj)
return rep.RepresentationIdentifier return rep.RepresentationIdentifier
@classmethod @classmethod
def representation_type(cls): def representation_type(cls):
props = bpy.context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
rep = tool.Geometry.get_active_representation(props.representation_obj) rep = tool.Geometry.get_active_representation(props.representation_obj)
return rep.RepresentationType return rep.RepresentationType
@classmethod @classmethod
def representation_usage(cls): def representation_usage(cls):
props = bpy.context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
return tool.Model.get_usage_type(tool.Ifc.get_entity(props.representation_obj)) return tool.Model.get_usage_type(tool.Ifc.get_entity(props.representation_obj))
@classmethod @classmethod
@@ -471,7 +471,7 @@ class AddBoolean(Operator, tool.Ifc.Operator):
second_items = [tool.Ifc.get().by_id(o.data.BIMMeshProperties.ifc_definition_id) for o in second_objs] second_items = [tool.Ifc.get().by_id(o.data.BIMMeshProperties.ifc_definition_id) for o in second_objs]
booleans = ifcopenshell.api.geometry.add_boolean(tool.Ifc.get(), first_item, second_items, props.operator) booleans = ifcopenshell.api.geometry.add_boolean(tool.Ifc.get(), first_item, second_items, props.operator)
rep_obj = bpy.context.scene.BIMGeometryProperties.representation_obj rep_obj = tool.Geometry.get_geometry_props().representation_obj
rep_element = tool.Ifc.get_entity(rep_obj) rep_element = tool.Ifc.get_entity(rep_obj)
tool.Model.mark_manual_booleans(rep_element, booleans) tool.Model.mark_manual_booleans(rep_element, booleans)
tool.Geometry.reload_representation(rep_obj) tool.Geometry.reload_representation(rep_obj)
@@ -826,7 +826,8 @@ class RemoveBoolean(Operator, tool.Ifc.Operator):
tool.Ifc.get(), tool.Ifc.get().by_id(props.active_boolean.ifc_definition_id) tool.Ifc.get(), tool.Ifc.get().by_id(props.active_boolean.ifc_definition_id)
) )
bpy.ops.bim.enable_editing_booleans() bpy.ops.bim.enable_editing_booleans()
rep_obj = bpy.context.scene.BIMGeometryProperties.representation_obj rep_obj = tool.Geometry.get_geometry_props().representation_obj
assert rep_obj
tool.Geometry.reload_representation(rep_obj) tool.Geometry.reload_representation(rep_obj)
tool.Root.reload_item_decorator() tool.Root.reload_item_decorator()
+4 -2
View File
@@ -125,7 +125,8 @@ class BooleansData:
@classmethod @classmethod
def booleans(cls): def booleans(cls):
obj = bpy.context.scene.BIMGeometryProperties.representation_obj or bpy.context.active_object props = tool.Geometry.get_geometry_props()
obj = props.representation_obj or bpy.context.active_object
if ( if (
not obj.data not obj.data
or not hasattr(obj.data, "BIMMeshProperties") or not hasattr(obj.data, "BIMMeshProperties")
@@ -138,7 +139,8 @@ class BooleansData:
@classmethod @classmethod
def manual_booleans(cls): def manual_booleans(cls):
obj = bpy.context.scene.BIMGeometryProperties.representation_obj or bpy.context.active_object props = tool.Geometry.get_geometry_props()
obj = props.representation_obj or bpy.context.active_object
if ( if (
not obj.data not obj.data
or not hasattr(obj.data, "BIMMeshProperties") or not hasattr(obj.data, "BIMMeshProperties")
@@ -311,8 +311,11 @@ class EnableEditingBooleans(bpy.types.Operator):
def execute(self, context): def execute(self, context):
props = context.scene.BIMBooleanProperties props = context.scene.BIMBooleanProperties
rep_obj = bpy.context.scene.BIMGeometryProperties.representation_obj gprops = tool.Geometry.get_geometry_props()
rep_obj = gprops.representation_obj
assert rep_obj
representation = tool.Geometry.get_active_representation(rep_obj) representation = tool.Geometry.get_active_representation(rep_obj)
assert representation
representation = ifcopenshell.util.representation.resolve_representation(representation) representation = ifcopenshell.util.representation.resolve_representation(representation)
props.booleans.clear() props.booleans.clear()
+7 -5
View File
@@ -174,7 +174,7 @@ class Geometry(bonsai.core.tool.Geometry):
@classmethod @classmethod
def delete_ifc_item(cls, obj: bpy.types.Object) -> None: def delete_ifc_item(cls, obj: bpy.types.Object) -> None:
props = bpy.context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
if len(props.item_objs) == 1: if len(props.item_objs) == 1:
return return
for i, item_obj in enumerate(props.item_objs): for i, item_obj in enumerate(props.item_objs):
@@ -1622,7 +1622,7 @@ class Geometry(bonsai.core.tool.Geometry):
@classmethod @classmethod
def sync_item_positions(cls) -> None: def sync_item_positions(cls) -> None:
props = bpy.context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
if not props.representation_obj: if not props.representation_obj:
return return
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
@@ -1732,7 +1732,7 @@ class Geometry(bonsai.core.tool.Geometry):
@classmethod @classmethod
def import_item(cls, obj: bpy.types.Object) -> None: def import_item(cls, obj: bpy.types.Object) -> None:
props = bpy.context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
rep_obj = props.representation_obj rep_obj = props.representation_obj
tool.Loader.settings.contexts = ifcopenshell.util.representation.get_prioritised_contexts(tool.Ifc.get()) tool.Loader.settings.contexts = ifcopenshell.util.representation.get_prioritised_contexts(tool.Ifc.get())
tool.Loader.settings.context_settings = tool.Loader.create_settings() tool.Loader.settings.context_settings = tool.Loader.create_settings()
@@ -1792,7 +1792,7 @@ class Geometry(bonsai.core.tool.Geometry):
@classmethod @classmethod
def disable_item_mode(cls) -> None: def disable_item_mode(cls) -> None:
props = bpy.context.scene.BIMGeometryProperties props = tool.Geometry.get_geometry_props()
if props.representation_obj: if props.representation_obj:
props.representation_obj.hide_set(False) props.representation_obj.hide_set(False)
cls.unlock_object(props.representation_obj) cls.unlock_object(props.representation_obj)
@@ -1815,7 +1815,9 @@ class Geometry(bonsai.core.tool.Geometry):
builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get()) builder = ifcopenshell.util.shape_builder.ShapeBuilder(tool.Ifc.get())
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get()) unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
rep_obj = bpy.context.scene.BIMGeometryProperties.representation_obj props = tool.Geometry.get_geometry_props()
rep_obj = props.representation_obj
assert rep_obj
if (coordinate_offset := cls.get_cartesian_point_offset(rep_obj)) is not None: if (coordinate_offset := cls.get_cartesian_point_offset(rep_obj)) is not None:
verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices] verts = [((np.array(v.co) + coordinate_offset) / unit_scale).tolist() for v in obj.data.vertices]
else: else:
+2
View File
@@ -18,6 +18,8 @@
import bpy import bpy
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.geolocation
import ifcopenshell.util.unit
import bonsai.core.tool import bonsai.core.tool
import bonsai.tool as tool import bonsai.tool as tool
import numpy as np import numpy as np
+3 -3
View File
@@ -457,13 +457,13 @@ class TestSelectConnection(NewFile):
class TestShouldForceFacetedBrep(NewFile): class TestShouldForceFacetedBrep(NewFile):
def test_run(self): def test_run(self):
result = bpy.context.scene.BIMGeometryProperties.should_force_faceted_brep result = tool.Geometry.get_geometry_props().should_force_faceted_brep
assert subject.should_force_faceted_brep() is result assert subject.should_force_faceted_brep() is result
class TestShouldForceTriangulation(NewFile): class TestShouldForceTriangulation(NewFile):
def test_run(self): def test_run(self):
result = bpy.context.scene.BIMGeometryProperties.should_force_triangulation result = tool.Geometry.get_geometry_props().should_force_triangulation
assert subject.should_force_triangulation() is result assert subject.should_force_triangulation() is result
@@ -519,7 +519,7 @@ class TestShouldGenerateUVs(NewFile):
class TestShouldUsePresentationStyleAssignment(NewFile): class TestShouldUsePresentationStyleAssignment(NewFile):
def test_run(self): def test_run(self):
result = bpy.context.scene.BIMGeometryProperties.should_use_presentation_style_assignment result = tool.Geometry.get_geometry_props().should_use_presentation_style_assignment
assert subject.should_use_presentation_style_assignment() is result assert subject.should_use_presentation_style_assignment() is result
@@ -1282,7 +1282,7 @@ class ShapeBuilder:
) )
return points, segments, transition_arc return points, segments, transition_arc
def mesh(self, points: list[list[float]], faces: list[list[int]]) -> ifcopenshell.entity_instance: def mesh(self, points: SequenceOfVectors, faces: Sequence[Sequence[int]]) -> ifcopenshell.entity_instance:
if self.file.schema == "IFC2X3": if self.file.schema == "IFC2X3":
return self.faceted_brep(points, faces) return self.faceted_brep(points, faces)
return self.polygonal_face_set(points, faces) return self.polygonal_face_set(points, faces)