mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 22:20:00 +00:00
Lock scale for aggregate parts too if aggregate has openings
This commit is contained in:
@@ -254,6 +254,8 @@ class IfcImporter:
|
|||||||
self.profile_code("Place objects in collections")
|
self.profile_code("Place objects in collections")
|
||||||
self.setup_arrays()
|
self.setup_arrays()
|
||||||
self.profile_code("Setup arrays")
|
self.profile_code("Setup arrays")
|
||||||
|
self.lock_scales()
|
||||||
|
self.profile_code("Lock objects scales")
|
||||||
self.add_project_to_scene()
|
self.add_project_to_scene()
|
||||||
self.profile_code("Add project to scene")
|
self.profile_code("Add project to scene")
|
||||||
if self.ifc_import_settings.should_clean_mesh and len(self.file.by_type("IfcElement")) < 1000:
|
if self.ifc_import_settings.should_clean_mesh and len(self.file.by_type("IfcElement")) < 1000:
|
||||||
@@ -811,8 +813,6 @@ class IfcImporter:
|
|||||||
|
|
||||||
obj = bpy.data.objects.new(tool.Loader.get_name(element), mesh)
|
obj = bpy.data.objects.new(tool.Loader.get_name(element), mesh)
|
||||||
self.link_element(element, obj)
|
self.link_element(element, obj)
|
||||||
if getattr(element, "HasOpenings", None):
|
|
||||||
tool.Geometry.lock_scale(obj)
|
|
||||||
|
|
||||||
if shape:
|
if shape:
|
||||||
# We use numpy here because Blender mathutils.Matrix is not accurate enough
|
# We use numpy here because Blender mathutils.Matrix is not accurate enough
|
||||||
@@ -1157,6 +1157,20 @@ class IfcImporter:
|
|||||||
tool.Blender.Modifier.Array.set_children_lock_state(element, i, True)
|
tool.Blender.Modifier.Array.set_children_lock_state(element, i, True)
|
||||||
tool.Blender.Modifier.Array.constrain_children_to_parent(element)
|
tool.Blender.Modifier.Array.constrain_children_to_parent(element)
|
||||||
|
|
||||||
|
def lock_scales(self) -> None:
|
||||||
|
elements = set(self.file.by_type("IfcProduct"))
|
||||||
|
while elements:
|
||||||
|
element = elements.pop()
|
||||||
|
if not getattr(element, "HasOpenings", False):
|
||||||
|
continue
|
||||||
|
voided_elements = tool.Aggregate.get_parts_recursively(element)
|
||||||
|
voided_elements.add(element)
|
||||||
|
elements.difference_update(voided_elements)
|
||||||
|
for element in voided_elements:
|
||||||
|
if not (obj := tool.Ifc.get_object(element)):
|
||||||
|
continue
|
||||||
|
tool.Geometry.lock_scale(obj)
|
||||||
|
|
||||||
|
|
||||||
class IfcImportSettings:
|
class IfcImportSettings:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|||||||
@@ -197,9 +197,7 @@ class RemoveOpening(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
is_global=True,
|
is_global=True,
|
||||||
should_sync_changes_first=False,
|
should_sync_changes_first=False,
|
||||||
)
|
)
|
||||||
if building_obj and not getattr(element, "HasOpenings", None):
|
tool.Geometry.unlock_scale_object_with_openings(obj)
|
||||||
tool.Geometry.unlock_scale(building_obj)
|
|
||||||
|
|
||||||
tool.Geometry.clear_cache(element)
|
tool.Geometry.clear_cache(element)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|||||||
@@ -73,3 +73,13 @@ class Aggregate(bonsai.core.tool.Aggregate):
|
|||||||
for rel in related_element.Decomposes:
|
for rel in related_element.Decomposes:
|
||||||
if rel.is_a("IfcRelAggregates"):
|
if rel.is_a("IfcRelAggregates"):
|
||||||
return rel.RelatingObject
|
return rel.RelatingObject
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_parts_recursively(cls, element: ifcopenshell.entity_instance) -> set[ifcopenshell.entity_instance]:
|
||||||
|
parts = set()
|
||||||
|
queue = {element}
|
||||||
|
while queue:
|
||||||
|
element = queue.pop()
|
||||||
|
queue.update(new_parts := set(ifcopenshell.util.element.get_parts(element)))
|
||||||
|
parts.update(new_parts)
|
||||||
|
return parts
|
||||||
|
|||||||
@@ -148,6 +148,19 @@ class Geometry(bonsai.core.tool.Geometry):
|
|||||||
def unlock_scale(cls, obj: bpy.types.Object) -> None:
|
def unlock_scale(cls, obj: bpy.types.Object) -> None:
|
||||||
obj.lock_scale = (False, False, False)
|
obj.lock_scale = (False, False, False)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def unlock_scale_object_with_openings(cls, obj: bpy.types.Object) -> None:
|
||||||
|
element = tool.Ifc.get_entity(obj)
|
||||||
|
queue = {element}
|
||||||
|
while queue:
|
||||||
|
element = queue.pop()
|
||||||
|
if getattr(element, "HasOpenings", None):
|
||||||
|
# Part still has openings, keep it locked.
|
||||||
|
continue
|
||||||
|
obj = tool.Ifc.get_object(element)
|
||||||
|
cls.unlock_scale(obj)
|
||||||
|
queue.update(new_parts := set(ifcopenshell.util.element.get_parts(element)))
|
||||||
|
|
||||||
@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 = bpy.context.scene.BIMGeometryProperties
|
||||||
|
|||||||
Reference in New Issue
Block a user