2020import ifcopenshell .api
2121from geometry import GeometryIO
2222from datetime import datetime
23+ import os
2324
2425JSON_TO_IFC = {
2526 "Building" : ["IfcBuilding" ],
@@ -75,7 +76,7 @@ def __init__(self):
7576 self .configuration ()
7677
7778 def configuration (self , file_destination = "output.ifc" , name_attribute = None , split = True ):
78- self .properties ["file_destination" ] = file_destination
79+ self .properties ["file_destination" ], self . properties [ "file_extension" ] = os . path . splitext ( file_destination )
7980 self .properties ["name_attribute" ] = name_attribute
8081 self .properties ["split" ] = split
8182
@@ -88,7 +89,10 @@ def convert(self, city_model):
8889 scale = self .properties ["local_scale" ])
8990 # self.build_vertices()
9091 self .create_IFC_classes ()
91- self .write_file ()
92+ if self .properties ["split" ]:
93+ self .write_files ()
94+ else :
95+ self .write_file ()
9296
9397 def create_metadata (self ):
9498 # Georeferencing
@@ -107,13 +111,13 @@ def create_metadata(self):
107111 if epsg :
108112 # Meter is assumed as unit for now
109113 unit = self .IFC_model .createIfcSIUnit (None , "LENGTHUNIT" , None , "METRE" )
110- crs = self .IFC_model .create_entity ("IfcProjectedCrs" , Name = f"epsg:{ epsg } " )
111- self .IFC_model . create_entity ( "IfcMapConversion" , self .IFC_representation_context ,
112- ** self .properties ["local_translation" ])
114+ self . properties [ "local_translation" ][ "TargetCRS" ] = self .IFC_model .create_entity ("IfcProjectedCrs" , Name = f"epsg:{ epsg } " )
115+ self .properties [ "local_translation" ][ "SourceCRS" ] = self .IFC_representation_context
116+ self . IFC_model . create_entity ( "IfcMapConversion" , ** self .properties ["local_translation" ])
113117
114118 def create_new_file (self ):
115119 self .IFC_model = ifcopenshell .api .run ("project.create_file" )
116- self .IFC_project = ifcopenshell .api .run ("root.create_entity" , self .IFC_model , ** {"ifc_class" : "IfcProject" })
120+ self .IFC_project = ifcopenshell .api .run ("root.create_entity" , self .IFC_model , ** {"ifc_class" : "IfcProject" , "name" : "My Project" })
117121 ifcopenshell .api .run ("unit.assign_unit" , self .IFC_model , length = {"is_metric" : True , "raw" : "METERS" })
118122 self .properties ["owner_history" ] = self .create_owner_history ()
119123 self .IFC_representation_context = ifcopenshell .api .run ("context.add_context" , self .IFC_model ,
@@ -139,6 +143,10 @@ def create_new_file(self):
139143 self .IFC_site = ifcopenshell .api .run ("root.create_entity" , self .IFC_model ,
140144 ** {"ifc_class" : "IfcSite" ,
141145 "name" : "My Site" })
146+ self .IFC_model .create_entity ("IfcRelAggregates" ,
147+ ** {"GlobalId" : ifcopenshell .guid .new (),
148+ "RelatedObjects" : [self .IFC_site ],
149+ "RelatingObject" : self .IFC_project })
142150
143151 def create_owner_history (self ):
144152 actor = self .IFC_model .createIfcActorRole ("ENGINEER" , None , None )
@@ -157,7 +165,31 @@ def create_owner_history(self):
157165 return ownerHistory
158166
159167 def write_file (self ):
160- self .IFC_model .write (self .properties ["file_destination" ])
168+ file = self .properties ["file_destination" ] + self .properties ["file_extension" ]
169+ self .IFC_model .write (file )
170+
171+ def write_files (self ):
172+ for lod , IFC_representation_sub_context in self .IFC_representation_sub_contexts .items ():
173+ sub_context_id = IFC_representation_sub_context .id ()
174+
175+ # TODO this method makes a copy of the IFC_model by writing it and importing it,
176+ # TODO but maybe there is a better method.
177+ file = self .properties ["file_destination" ] + lod + self .properties ["file_extension" ]
178+ self .IFC_model .write (file )
179+ IFC_copied_model = ifcopenshell .open (file )
180+
181+ IFC_copied_model_sub_contexts = IFC_copied_model .by_type ('IfcGeometricRepresentationSubContext' )
182+ for sub_context in IFC_copied_model_sub_contexts :
183+ if sub_context .id () == sub_context_id :
184+ continue
185+ else :
186+ elements = IFC_copied_model .get_inverse (sub_context )
187+ for element in elements :
188+ IFC_copied_model .remove (element )
189+ IFC_copied_model .remove (sub_context )
190+
191+ IFC_copied_model .write (file )
192+ del IFC_copied_model
161193
162194 def create_IFC_classes (self ):
163195 parents_children_relations = {"IfcSite" : {'Parent' : self .IFC_site , 'Children' : []}}
@@ -223,14 +255,21 @@ def create_IFC_classes(self):
223255 parents_children_relations [obj_id ]['Parent' ] = IFC_object
224256
225257 if IFC_semantic_surface_children :
226- self .IFC_model .create_entity ("IfcRelAggregates " ,
258+ self .IFC_model .create_entity ("IfcRelContainedInSpatialStructure " ,
227259 ** {"GlobalId" : ifcopenshell .guid .new (),
228- "RelatedObjects " : IFC_semantic_surface_children ,
229- "RelatingObject " : IFC_object })
260+ "RelatedElements " : IFC_semantic_surface_children ,
261+ "RelatingStructure " : IFC_object })
230262
231263 self .create_property_set (obj .attributes , IFC_object )
232264
233- for parent_children in parents_children_relations .values ():
265+ for parent , parent_children in parents_children_relations .items ():
266+ if parent == "IfcSite" :
267+ self .IFC_model .create_entity ("IfcRelAggregates" ,
268+ ** {"GlobalId" : ifcopenshell .guid .new (),
269+ "RelatedObjects" : parent_children ['Children' ],
270+ "RelatingObject" : parent_children ['Parent' ]})
271+ continue
272+
234273 self .IFC_model .create_entity ("IfcRelContainedInSpatialStructure" ,
235274 ** {"GlobalId" : ifcopenshell .guid .new (),
236275 "RelatedElements" : parent_children ['Children' ],
@@ -248,8 +287,11 @@ def create_IFC_semantic_surface_children(self, geometry, lod):
248287 # CREATE ENTITY
249288 surface_geometry = self .geometry .create_IFC_surface (self .IFC_model , geometry , surface_id )
250289 if surface_geometry :
251- child_data ["Representation" ] = self .create_IFC_shape_representation (surface_geometry , 'brep' , lod )
290+ IFC_shape_representation = self .create_IFC_shape_representation (surface_geometry , 'brep' , lod )
291+ child_data ["Representation" ] = self .IFC_model .create_entity ("IfcProductDefinitionShape" ,
292+ Representations = [IFC_shape_representation ])
252293 IFC_semantic_surface_children .append (self .IFC_model .create_entity (IFC_child_class , ** child_data ))
294+
253295 return IFC_semantic_surface_children
254296
255297 def create_IFC_shape_representation (self , IFC_geometry , shape_representation_type , lod ):
0 commit comments