mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Fix #3069. WARNING: dangerous change. Objects that have their own collection now have a pointer to that collection. This fixes a variety of subtle sync bugs.
This commit is contained in:
@@ -111,6 +111,7 @@ classes = [
|
||||
prop.PsetQto,
|
||||
prop.GlobalId,
|
||||
prop.BIMObjectProperties,
|
||||
prop.BIMCollectionProperties,
|
||||
prop.BIMMaterialProperties,
|
||||
prop.BIMMeshProperties,
|
||||
ui.BIM_PT_section_plane,
|
||||
@@ -158,6 +159,7 @@ def register():
|
||||
bpy.app.handlers.load_post.append(handler.loadIfcStore)
|
||||
bpy.app.handlers.save_post.append(handler.ensureIfcExported)
|
||||
bpy.types.Scene.BIMProperties = bpy.props.PointerProperty(type=prop.BIMProperties)
|
||||
bpy.types.Collection.BIMCollectionProperties = bpy.props.PointerProperty(type=prop.BIMCollectionProperties)
|
||||
bpy.types.Object.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
|
||||
bpy.types.Material.BIMObjectProperties = bpy.props.PointerProperty(type=prop.BIMObjectProperties)
|
||||
bpy.types.Material.BIMMaterialProperties = bpy.props.PointerProperty(type=prop.BIMMaterialProperties)
|
||||
@@ -195,6 +197,7 @@ def unregister():
|
||||
bpy.app.handlers.load_post.remove(handler.loadIfcStore)
|
||||
bpy.app.handlers.save_post.remove(handler.ensureIfcExported)
|
||||
del bpy.types.Scene.BIMProperties
|
||||
del bpy.types.Collection.BIMCollectionProperties
|
||||
del bpy.types.Object.BIMObjectProperties
|
||||
del bpy.types.Material.BIMObjectProperties
|
||||
del bpy.types.Material.BIMMaterialProperties
|
||||
|
||||
@@ -1337,8 +1337,9 @@ class IfcImporter:
|
||||
"{}/{}".format(self.project["ifc"].is_a(), self.project["ifc"].Name)
|
||||
)
|
||||
obj = self.create_product(self.project["ifc"])
|
||||
if obj:
|
||||
self.project["blender"].objects.link(obj)
|
||||
self.project["blender"].objects.link(obj)
|
||||
self.project["blender"].BIMCollectionProperties.obj = obj
|
||||
obj.BIMObjectProperties.collection = self.project["blender"]
|
||||
|
||||
def create_collections(self):
|
||||
if self.ifc_import_settings.collection_mode == "DECOMPOSITION":
|
||||
@@ -1673,6 +1674,8 @@ class IfcImporter:
|
||||
return
|
||||
elif element.GlobalId in self.collections:
|
||||
collection = self.collections[element.GlobalId]
|
||||
collection.BIMCollectionProperties.obj = obj
|
||||
obj.BIMObjectProperties.collection = collection
|
||||
collection.name = obj.name
|
||||
return collection.objects.link(obj)
|
||||
elif getattr(element, "Decomposes", None):
|
||||
@@ -1687,7 +1690,10 @@ class IfcImporter:
|
||||
elif element.is_a("IfcGridAxis"):
|
||||
return
|
||||
elif element.GlobalId in self.collections:
|
||||
return self.collections[element.GlobalId].objects.link(obj)
|
||||
collection = self.collections[element.GlobalId]
|
||||
collection.BIMCollectionProperties.obj = obj
|
||||
obj.BIMObjectProperties.collection = collection
|
||||
return collection.objects.link(obj)
|
||||
elif element.is_a("IfcTypeObject"):
|
||||
return self.type_collection.objects.link(obj)
|
||||
elif element.is_a("IfcStructuralMember"):
|
||||
|
||||
@@ -409,7 +409,12 @@ class GlobalId(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
|
||||
|
||||
class BIMCollectionProperties(PropertyGroup):
|
||||
obj: PointerProperty(type=bpy.types.Object)
|
||||
|
||||
|
||||
class BIMObjectProperties(PropertyGroup):
|
||||
collection: PointerProperty(type=bpy.types.Collection)
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
blender_offset_type: EnumProperty(
|
||||
items=[(o, o, "") for o in ["NONE", "OBJECT_PLACEMENT", "CARTESIAN_POINT"]],
|
||||
|
||||
@@ -59,17 +59,18 @@ class Collector(blenderbim.core.tool.Collector):
|
||||
parent_collection = collection
|
||||
break
|
||||
|
||||
if parent_collection:
|
||||
parent_obj = bpy.data.objects.get(parent_collection.name)
|
||||
parent = tool.Ifc.get_entity(parent_obj)
|
||||
if parent:
|
||||
# This is lazy, but works. One of these will succeed, the other will fail silently.
|
||||
blenderbim.core.spatial.assign_container(
|
||||
tool.Ifc, tool.Collector, tool.Spatial, structure_obj=parent_obj, element_obj=obj
|
||||
)
|
||||
blenderbim.core.aggregate.assign_object(
|
||||
tool.Ifc, tool.Aggregate, tool.Collector, relating_obj=parent_obj, related_obj=obj
|
||||
)
|
||||
if not parent_collection:
|
||||
return
|
||||
|
||||
parent = tool.Ifc.get_entity(parent_collection.BIMCollectionProperties.obj)
|
||||
if parent:
|
||||
# This is lazy, but works. One of these will succeed, the other will fail silently.
|
||||
blenderbim.core.spatial.assign_container(
|
||||
tool.Ifc, tool.Collector, tool.Spatial, structure_obj=parent_obj, element_obj=obj
|
||||
)
|
||||
blenderbim.core.aggregate.assign_object(
|
||||
tool.Ifc, tool.Aggregate, tool.Collector, relating_obj=parent_obj, related_obj=obj
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def assign(cls, obj):
|
||||
@@ -100,18 +101,21 @@ class Collector(blenderbim.core.tool.Collector):
|
||||
|
||||
@classmethod
|
||||
def _get_own_collection(cls, element, obj):
|
||||
if obj.BIMObjectProperties.collection:
|
||||
return obj.BIMObjectProperties.collection
|
||||
|
||||
if element.is_a("IfcProject"):
|
||||
return bpy.data.collections.get(obj.name) or bpy.data.collections.new(obj.name)
|
||||
return cls._create_own_collection(obj)
|
||||
|
||||
if tool.Ifc.get_schema() == "IFC2X3":
|
||||
if element.is_a("IfcSpatialStructureElement"):
|
||||
return bpy.data.collections.get(obj.name) or bpy.data.collections.new(obj.name)
|
||||
return cls._create_own_collection(obj)
|
||||
else:
|
||||
if element.is_a("IfcSpatialStructureElement") or element.is_a("IfcExternalSpatialStructureElement"):
|
||||
return bpy.data.collections.get(obj.name) or bpy.data.collections.new(obj.name)
|
||||
return cls._create_own_collection(obj)
|
||||
|
||||
if element.is_a("IfcGrid"):
|
||||
return bpy.data.collections.get(obj.name) or bpy.data.collections.new(obj.name)
|
||||
return cls._create_own_collection(obj)
|
||||
|
||||
if element.is_a("IfcGridAxis"):
|
||||
if element.PartOfU:
|
||||
@@ -125,7 +129,7 @@ class Collector(blenderbim.core.tool.Collector):
|
||||
axes = "WAxes"
|
||||
grid_obj = tool.Ifc.get_object(grid)
|
||||
if grid_obj:
|
||||
grid_col = bpy.data.collections.get(grid_obj.name)
|
||||
grid_col = cls._get_own_collection(grid, grid_obj)
|
||||
axes_col = [c for c in grid_col.children if axes in c.name]
|
||||
if axes_col:
|
||||
return axes_col[0]
|
||||
@@ -144,7 +148,7 @@ class Collector(blenderbim.core.tool.Collector):
|
||||
return bpy.data.collections.get("Connections") or bpy.data.collections.new("Connections")
|
||||
|
||||
if getattr(element, "IsDecomposedBy", None):
|
||||
return bpy.data.collections.get(obj.name) or bpy.data.collections.new(obj.name)
|
||||
return cls._create_own_collection(obj)
|
||||
|
||||
@classmethod
|
||||
def _get_collection(cls, element, obj):
|
||||
@@ -180,14 +184,14 @@ class Collector(blenderbim.core.tool.Collector):
|
||||
if aggregate:
|
||||
aggregate_obj = tool.Ifc.get_object(aggregate)
|
||||
if aggregate_obj:
|
||||
collection = bpy.data.collections.get(aggregate_obj.name)
|
||||
collection = aggregate_obj.BIMObjectProperties.collection
|
||||
if collection:
|
||||
return collection
|
||||
|
||||
container = ifcopenshell.util.element.get_container(element)
|
||||
if container:
|
||||
container_obj = tool.Ifc.get_object(container)
|
||||
collection = bpy.data.collections.get(container_obj.name)
|
||||
collection = container_obj.BIMObjectProperties.collection
|
||||
if collection:
|
||||
return collection
|
||||
|
||||
@@ -208,3 +212,10 @@ class Collector(blenderbim.core.tool.Collector):
|
||||
project_obj = tool.Ifc.get_object(tool.Ifc.get().by_type("IfcProject")[0])
|
||||
project_obj.users_collection[0].children.link(collection)
|
||||
return collection
|
||||
|
||||
@classmethod
|
||||
def _create_own_collection(cls, obj):
|
||||
collection = bpy.data.collections.new(obj.name)
|
||||
obj.BIMObjectProperties.collection = collection
|
||||
collection.BIMCollectionProperties.obj = obj
|
||||
return collection
|
||||
|
||||
@@ -153,6 +153,7 @@ class TestAssign(NewFile):
|
||||
tool.Ifc.link(space_element, space_obj)
|
||||
space_collection = bpy.data.collections.new("IfcSpace/Name")
|
||||
bpy.context.scene.collection.children.link(space_collection)
|
||||
space_obj.BIMObjectProperties.collection = space_collection
|
||||
space_collection.objects.link(space_obj)
|
||||
ifcopenshell.api.run(
|
||||
"aggregate.assign_object",
|
||||
|
||||
Reference in New Issue
Block a user