mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
generate_demo_library - sync guid on regeneration
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
ISO-10303-21;
|
||||
HEADER;
|
||||
FILE_DESCRIPTION(('ViewDefinition[DesignTransferView]'),'2;1');
|
||||
FILE_NAME('/dev/null','2024-03-03T16:03:58+11:00',(),(),'IfcOpenShell v0.7.0-eaa2aa05a','IfcOpenShell v0.7.0-eaa2aa05a','Nobody');
|
||||
FILE_NAME('/dev/null','2025-03-27T16:04:10+05:00',(''),(''),'IfcOpenShell 0.0.0','IfcOpenShell 0.0.0','Nobody');
|
||||
FILE_SCHEMA(('IFC4'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
@@ -11,7 +11,7 @@ DATA;
|
||||
#4=IFCSIUNIT(*,.LENGTHUNIT.,$,.METRE.);
|
||||
#5=IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
|
||||
#6=IFCSIUNIT(*,.VOLUMEUNIT.,$,.CUBIC_METRE.);
|
||||
#7=IFCUNITASSIGNMENT((#6,#4,#5));
|
||||
#7=IFCUNITASSIGNMENT((#4,#5,#6));
|
||||
#8=IFCCARTESIANPOINT((0.,0.,0.));
|
||||
#9=IFCDIRECTION((0.,0.,1.));
|
||||
#10=IFCDIRECTION((1.,0.,0.));
|
||||
@@ -29,7 +29,7 @@ DATA;
|
||||
#22=IFCMATERIALLAYERSET((#24),$,$);
|
||||
#23=IFCRELASSOCIATESMATERIAL('0khP_Smdj12f2JrOTRbRKj',$,$,$,(#21),#22);
|
||||
#24=IFCMATERIALLAYER(#20,0.05,$,$,$,$,$);
|
||||
#25=IFCRELDECLARES('31JriXdev6BP2sC9lcxdC1',$,$,$,#2,(#26,#48,#72,#59,#92,#30,#96,#63,#21,#54,#87,#210,#153,#34,#67,#38,#82,#77,#42));
|
||||
#25=IFCRELDECLARES('31JriXdev6BP2sC9lcxdC1',$,$,$,#2,(#96,#77,#63,#42,#21,#54,#87,#153,#210,#34,#67,#26,#48,#72,#59,#92,#38,#82,#30));
|
||||
#26=IFCWALLTYPE('3R5onkTtX1IxdCMPoThRaw',$,'WAL100',$,$,$,$,$,$,.NOTDEFINED.);
|
||||
#27=IFCMATERIALLAYERSET((#29),$,$);
|
||||
#28=IFCRELASSOCIATESMATERIAL('0$mXRPCT16nP6Q70XFNvZv',$,$,$,(#26),#27);
|
||||
|
||||
Binary file not shown.
@@ -32,13 +32,104 @@ import bonsai.tool as tool
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def sync_guids(target_file: ifcopenshell.file, source_file: ifcopenshell.file) -> None:
|
||||
|
||||
def sync_guid(element: ifcopenshell.entity_instance) -> None:
|
||||
"""Try to sync `element` guid with `source_file`.
|
||||
|
||||
Sync is assigning guid based on the first element from `source_file` that has a matching type and name.
|
||||
"""
|
||||
|
||||
if element.is_a("IfcTypeProduct") or element.is_a("IfcContext"):
|
||||
assert element.Name, element
|
||||
elements = source_file.by_type(element.is_a(), False)
|
||||
for element_ in elements:
|
||||
if element.Name == element_.Name:
|
||||
element.GlobalId = element_.GlobalId
|
||||
return
|
||||
print(
|
||||
f"WARNING! Couldn't find a matching element in the GUID source to sync guid for '{element.Name}' ({element})."
|
||||
)
|
||||
|
||||
def sync_pset(pset: ifcopenshell.entity_instance) -> None:
|
||||
element_types = pset.DefinesType
|
||||
assert len(element_types) == 1
|
||||
element_type: ifcopenshell.entity_instance = element_types[0]
|
||||
try:
|
||||
element_type_ = source_file.by_guid(element_type.GlobalId)
|
||||
except RuntimeError:
|
||||
# New type with pset was added.
|
||||
print(f"WARNING! Couldn't find a matching pset for '{pset.Name}' ({pset}).")
|
||||
return
|
||||
assert len(element_type_.HasPropertySets) == 1
|
||||
pset_ = element_type_.HasPropertySets[0]
|
||||
assert pset.Name == pset_.Name
|
||||
pset.GlobalId = pset_.GlobalId
|
||||
|
||||
def sync_rel(rel: ifcopenshell.entity_instance) -> None:
|
||||
if rel.is_a("IfcRelAssociatesMaterial"):
|
||||
related_objects = rel.RelatedObjects
|
||||
assert len(related_objects) == 1
|
||||
related_object = related_objects[0]
|
||||
try:
|
||||
related_object_ = source_file.by_guid(related_object.GlobalId)
|
||||
except RuntimeError:
|
||||
# New type with material was added.
|
||||
print(f"WARNING! Couldn't find a matching rel for '{rel}'.")
|
||||
return
|
||||
rel_ = next((r for r in related_object_.HasAssociations if r.is_a("IfcRelAssociatesMaterial")))
|
||||
assert rel_
|
||||
rel.GlobalId = rel_.GlobalId
|
||||
elif rel.is_a("IfcRelDeclares"):
|
||||
context = rel.RelatingContext
|
||||
try:
|
||||
context_ = source_file.by_guid(context.GlobalId)
|
||||
except RuntimeError:
|
||||
# New context was added.
|
||||
print(f"WARNING! Couldn't find a matching context for '{context}'.")
|
||||
return
|
||||
rel_ = context_.Declares[0]
|
||||
rel.GlobalId = rel_.GlobalId
|
||||
else:
|
||||
print(f"WARNING! Couldn't find a matching element in the GUID source to sync guid for '{rel}'.")
|
||||
|
||||
roots = target_file.by_type("IfcRoot")
|
||||
psets: list[ifcopenshell.entity_instance] = []
|
||||
rels: list[ifcopenshell.entity_instance] = []
|
||||
for element in roots:
|
||||
if element.is_a("IfcPropertySet"):
|
||||
psets.append(element)
|
||||
continue
|
||||
elif element.is_a("IfcRelationship"):
|
||||
rels.append(element)
|
||||
continue
|
||||
sync_guid(element)
|
||||
|
||||
for rel in rels:
|
||||
sync_rel(rel)
|
||||
|
||||
for pset in psets:
|
||||
sync_pset(pset)
|
||||
|
||||
|
||||
class LibraryGenerator:
|
||||
output_filename = "Demo Library.ifc"
|
||||
|
||||
guid_source: ifcopenshell.file
|
||||
"""Guid sync is needed to avoid unnecessary diffs
|
||||
and to avoid `append_asset` from identifying existing elements and as new ones.
|
||||
"""
|
||||
|
||||
def generate(self) -> None:
|
||||
assert bpy.context.blend_data
|
||||
opened_blend_file = Path(bpy.context.blend_data.filepath)
|
||||
assert (
|
||||
opened_blend_file.name == "demo-library.blend"
|
||||
), "This script must be run from the demo-library.blend file as it's using Blender objects to create representations."
|
||||
libraries_path = opened_blend_file.parent.parent / "bonsai" / "bim" / "data" / "libraries"
|
||||
|
||||
guid_source_filepath = libraries_path / f"IFC4 {self.output_filename}"
|
||||
self.guid_source = ifcopenshell.open(guid_source_filepath)
|
||||
|
||||
ifcopenshell.api.pre_listeners = {}
|
||||
ifcopenshell.api.post_listeners = {}
|
||||
@@ -48,6 +139,7 @@ class LibraryGenerator:
|
||||
|
||||
# Basic project setup.
|
||||
self.project = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcProject", name="Bonsai Demo")
|
||||
|
||||
self.library = ifcopenshell.api.root.create_entity(
|
||||
self.file, ifc_class="IfcProjectLibrary", name="Bonsai Demo Library"
|
||||
)
|
||||
@@ -188,7 +280,8 @@ class LibraryGenerator:
|
||||
self.create_text_type("TYPE-TAG", "capsule-tag", ["{{type.Name}}"])
|
||||
self.create_text_type("NAME-TAG", "capsule-tag", ["{{Name}}"])
|
||||
|
||||
self.file.write("IFC4 Demo Library.ifc")
|
||||
sync_guids(self.file, self.guid_source)
|
||||
self.file.write(libraries_path / f"{self.file.schema} {self.output_filename}")
|
||||
|
||||
def create_symbol_type(self, name: str, symbol: str) -> None:
|
||||
element = ifcopenshell.api.root.create_entity(self.file, ifc_class="IfcTypeProduct", name=name)
|
||||
@@ -288,4 +381,5 @@ class LibraryGenerator:
|
||||
ifcopenshell.api.project.assign_declaration(self.file, definitions=[element], relating_context=self.library)
|
||||
|
||||
|
||||
LibraryGenerator().generate()
|
||||
if __name__ == "__main__":
|
||||
LibraryGenerator().generate()
|
||||
|
||||
Reference in New Issue
Block a user