1515#
1616# You should have received a copy of the GNU Lesser General Public License
1717# along with ifccityjson. If not, see <http://www.gnu.org/licenses/>.
18+ import os
19+ import copy
1820
1921import ifcopenshell
2022import ifcopenshell .api
2123from geometry import GeometryIO
2224from datetime import datetime
23- import os
25+
2426
2527JSON_TO_IFC = {
2628 "Building" : ["IfcBuilding" ],
@@ -126,20 +128,9 @@ def create_new_file(self):
126128
127129 if not self .city_model .has_metadata () or "presentLoDs" not in self .city_model .j ["metadata" ]:
128130 self .city_model .update_metadata ()
129- self .IFC_representation_sub_contexts = {}
130- for lod in self .city_model .j ["metadata" ]["presentLoDs" ]:
131- # TODO in ifcopenshell.api.context.add_context add support for UserDefinedTargetView
132- # self.IFC_representation_sub_contexts[str(lod)] = ifcopenshell.api.run("context.add_context", self.IFC_model,
133- # **{"context": "Model",
134- # "subcontext": "Body",
135- # "target_view": "USERDEFINED",
136- # "UserDefinedTargetView":str(lod)})
137- self .IFC_representation_sub_contexts [str (lod )] = self .IFC_model .create_entity ("IfcGeometricRepresentationSubContext" ,
138- ** {"ContextType" : "Model" ,
139- "ContextIdentifier" : "Body" ,
140- "TargetView" : "USERDEFINED" ,
141- "ParentContext" : self .IFC_representation_context ,
142- "UserDefinedTargetView" : "LOD" + str (lod )})
131+
132+ # create IFC representation subcontexts from lods
133+ self .create_representation_sub_contexts ()
143134
144135 self .IFC_site = ifcopenshell .api .run ("root.create_entity" , self .IFC_model ,
145136 ** {"ifc_class" : "IfcSite" ,
@@ -149,6 +140,25 @@ def create_new_file(self):
149140 "RelatedObjects" : [self .IFC_site ],
150141 "RelatingObject" : self .IFC_project })
151142
143+ def create_representation_sub_contexts (self ):
144+ self .IFC_representation_sub_contexts = {}
145+ for lod in self .city_model .j ["metadata" ]["presentLoDs" ]:
146+ self .IFC_representation_sub_contexts [str (lod )] = self .create_representation_sub_context (lod )
147+
148+ def create_representation_sub_context (self , lod ):
149+ # TODO in ifcopenshell.api.context.add_context add support for UserDefinedTargetView
150+ # self.IFC_representation_sub_contexts[str(lod)] = ifcopenshell.api.run("context.add_context", self.IFC_model,
151+ # **{"context": "Model",
152+ # "subcontext": "Body",
153+ # "target_view": "USERDEFINED",
154+ # "UserDefinedTargetView":str(lod)})
155+ return self .IFC_model .create_entity ("IfcGeometricRepresentationSubContext" ,
156+ ** {"ContextType" : "Model" ,
157+ "ContextIdentifier" : "Body" ,
158+ "TargetView" : "USERDEFINED" ,
159+ "ParentContext" : self .IFC_representation_context ,
160+ "UserDefinedTargetView" : "LOD" + str (lod )})
161+
152162 def create_owner_history (self ):
153163 actor = self .IFC_model .createIfcActorRole ("ENGINEER" , None , None )
154164 person = self .IFC_model .createIfcPerson ("Oostwegel" , None , "L.J.N." , None , None , None , (actor ,))
@@ -178,24 +188,27 @@ def write_files(self):
178188 file = self .properties ["file_destination" ] + lod + self .properties ["file_extension" ]
179189 self .IFC_model .write (file )
180190 IFC_copied_model = ifcopenshell .open (file )
181-
182191 IFC_copied_model_sub_contexts = IFC_copied_model .by_type ('IfcGeometricRepresentationSubContext' )
183192 for sub_context in IFC_copied_model_sub_contexts :
193+ print (sub_context )
184194 if sub_context .id () == sub_context_id :
185195 continue
186- else :
187- elements = IFC_copied_model .get_inverse (sub_context )
188- for element in elements :
189- IFC_copied_model .remove (element )
190- IFC_copied_model .remove (sub_context )
196+
197+ representations_in_context = sub_context .RepresentationsInContext
198+ for element in representations_in_context :
199+ IFC_copied_model .remove (element )
200+ # slow:
201+ # ifcopenshell.api.run("geometry.remove_representation", IFC_copied_model, representation=element)
202+
203+ ifcopenshell .api .run ("context.remove_context" , IFC_copied_model , context = sub_context )
191204
192205 IFC_copied_model .write (file )
193206 del IFC_copied_model
194207
195208 def create_IFC_classes (self ):
196209 parents_children_relations = {"IfcSite" : {'Parent' : self .IFC_site , 'Children' : []}}
210+ geometries = {}
197211 for obj_id , obj in self .city_model .get_cityobjects ().items ():
198-
199212 # CityJSON type to class
200213 mapping = JSON_TO_IFC [obj .type ]
201214 IFC_class = mapping [0 ]
@@ -210,21 +223,23 @@ def create_IFC_classes(self):
210223 if "name_attribute" in self .properties and self .properties ["name_attribute" ] in obj .attributes :
211224 IFC_name = obj .attributes [self .properties ["name_attribute" ]]
212225
213- # geometry_lod
214- lod = 0
215- geometry = None
216226 if len (obj .geometry ) == 0 :
217227 print (f"Warning: Object { obj_id } has no geometry." )
218228
219229 IFC_semantic_surface_children = []
220230 IFC_shape_representations = []
221231 for geometry in obj .geometry :
222232 lod = geometry .lod
233+ if str (lod ) != '1.3' : # TODO: split LODS
234+ continue
235+ if str (lod ) not in self .IFC_representation_sub_contexts :
236+ self .IFC_representation_sub_contexts [str (lod )] = self .create_representation_sub_context (lod )
237+
223238 IFC_geometry , shape_representation_type = None , None
224- # representation = self.create_IFC_LOD_representation(obj, geometry)
239+
225240 if geometry and geometry .surfaces :
226- IFC_semantic_surface_children = self .create_IFC_semantic_surface_children (geometry , lod )
227- if geometry :
241+ IFC_semantic_surface_children . extend ( self .create_IFC_semantic_surface_children (geometry , lod ) )
242+ elif geometry :
228243 IFC_geometry , shape_representation_type = self .geometry .create_IFC_geometry (self .IFC_model ,
229244 geometry )
230245 if IFC_geometry :
@@ -264,17 +279,10 @@ def create_IFC_classes(self):
264279 self .create_property_set (obj .attributes , IFC_object )
265280
266281 for parent , parent_children in parents_children_relations .items ():
267- if parent == "IfcSite" :
268- self .IFC_model .create_entity ("IfcRelAggregates" ,
269- ** {"GlobalId" : ifcopenshell .guid .new (),
270- "RelatedObjects" : parent_children ['Children' ],
271- "RelatingObject" : parent_children ['Parent' ]})
272- continue
273-
274- self .IFC_model .create_entity ("IfcRelContainedInSpatialStructure" ,
282+ self .IFC_model .create_entity ("IfcRelAggregates" ,
275283 ** {"GlobalId" : ifcopenshell .guid .new (),
276- "RelatedElements " : parent_children ['Children' ],
277- "RelatingStructure " : parent_children ['Parent' ]}
284+ "RelatedObjects " : parent_children ['Children' ],
285+ "RelatingObject " : parent_children ['Parent' ]}
278286 )
279287
280288 def create_IFC_semantic_surface_children (self , geometry , lod ):
@@ -289,6 +297,7 @@ def create_IFC_semantic_surface_children(self, geometry, lod):
289297 surface_geometry = self .geometry .create_IFC_surface (self .IFC_model , geometry , surface_id )
290298 if surface_geometry :
291299 IFC_shape_representation = self .create_IFC_shape_representation (surface_geometry , 'brep' , lod )
300+
292301 child_data ["Representation" ] = self .IFC_model .create_entity ("IfcProductDefinitionShape" ,
293302 Representations = [IFC_shape_representation ])
294303 IFC_semantic_surface_children .append (self .IFC_model .create_entity (IFC_child_class , ** child_data ))
@@ -306,31 +315,8 @@ def create_IFC_shape_representation(self, IFC_geometry, shape_representation_typ
306315 return shape_representation
307316
308317 def create_property_set (self , CJ_attributes , IFC_entity ):
309- IFC_object_properties = []
310- for property , val in CJ_attributes .items ():
311- if val == None :
312- continue
313-
314- if type (val ) == int :
315- IFC_type = "IfcInteger"
316- elif type (val ) == float :
317- IFC_type = "IfcReal"
318- elif type (val ) == bool :
319- IFC_type = "IfcBoolean"
320- else :
321- IFC_type = "IfcText"
322-
323- IFC_object_properties .append (
324- self .IFC_model .createIfcPropertySingleValue (property , property ,
325- self .IFC_model .create_entity (IFC_type , val ), None )
326- )
327- property_set = self .IFC_model .createIfcPropertySet (ifcopenshell .guid .new (),
328- self .properties ["owner_history" ],
329- "CityJSON_attributes" ,
330- None ,
331- IFC_object_properties )
332-
333- self .IFC_model .createIfcRelDefinesByProperties (ifcopenshell .guid .new (),
334- self .properties ["owner_history" ],
335- None , None , [IFC_entity ],
336- property_set )
318+ if len (CJ_attributes ) == 0 :
319+ return
320+
321+ pset = ifcopenshell .api .run ("pset.add_pset" , self .IFC_model , product = IFC_entity , name = "CityJSON_attributes" )
322+ ifcopenshell .api .run ("pset.edit_pset" , self .IFC_model , pset = pset , properties = CJ_attributes )
0 commit comments