4242 'ContainsElements'
4343}
4444
45+
4546class IFC2JSON5a :
4647 def __init__ (self , ifcFilePath ):
4748 self .ifcFilePath = ifcFilePath
@@ -55,7 +56,7 @@ def __init__(self, ifcFilePath):
5556
5657 def spf2Json (self ):
5758 objData = self .getObjData (self .ifcFilePath )
58- jsonObjects = []
59+ jsonObjects = []
5960 # entityIter = iter(self.ifcModel)
6061 # for entity in entityIter:
6162 # # print(dir(entity))
@@ -68,23 +69,25 @@ def spf2Json(self):
6869 jsonObjects .append (self .id_objects [key ])
6970 for key in self .representations :
7071 jsonObjects .append (self .representations [key ])
71- return {'file_schema' : 'IFC.JSON5a' ,'data' : jsonObjects }
72+ return {
73+ 'file_schema' : 'IFC.JSON5a' ,
74+ 'originatingSystem' : 'IFC2JSON_python' ,
75+ 'data' : jsonObjects
76+ }
7277
7378 def entityToDict (self , entity , objData , parent = None ):
74- entityAttributes = entity .__dict__
75- # inverseAttributes = explicitInverseAttributes.intersection(entity.wrapped_data.get_inverse_attribute_names())
76- entityType = entity .is_a ()
77- entityType = entityType [3 :]
7879
79- # Entitie names must be in camelCase
80- entityType = entityType [ 0 ]. lower () + entityType [ 1 :]
80+ # Entity names must be in camelCase and stripped of Ifc prefix
81+ entityType = common . toLowerCamelcase ( entity . is_a ()[ 3 :])
8182
83+ entityAttributes = entity .__dict__
84+ # inverseAttributes = explicitInverseAttributes.intersection(entity.wrapped_data.get_inverse_attribute_names())
85+
8286 ref = {
8387 'type' : entityType
8488 }
8589
86-
87- # determine if object needs to be nested or referenced
90+ # All objects with a GlobalId must be referenced, all others nested
8891 reference = False
8992 if 'GlobalId' in entityAttributes :
9093 reference = True
@@ -95,15 +98,13 @@ def entityToDict(self, entity, objData, parent=None):
9598 'type' : entityType
9699 }
97100
98-
99101 # for inverseAttribute in inverseAttributes:
100102 # invAtt = {}
101103 # attributeObject = getattr(entity, inverseAttribute)
102104 # attr = inverseAttribute
103105 # attrKey = common.toLowerCamelcase(attr)
104106 # print(attributeObject)
105-
106- # print("yeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeees")
107+
107108 # if isinstance(attributeObject, ifcopenshell.entity_instance):
108109 # print("dsicnkjcnkdjvnskjcnkvjnfjkn")
109110 # # if attributeObject.is_a == 'IfcRelAggregates':
@@ -132,7 +133,6 @@ def entityToDict(self, entity, objData, parent=None):
132133 # # print(inverseAttribute)
133134 # d[inverseAttribute] = invAtt
134135
135-
136136 # if hasattr(entity, 'IsDefinedBy'):
137137 # decomposedBy = entity.IsDefinedBy
138138 # invAtt = []
@@ -150,7 +150,6 @@ def entityToDict(self, entity, objData, parent=None):
150150 # if invAtt:
151151 # d['IsDefinedBy'] = invAtt
152152
153-
154153 if hasattr (entity , 'IsDefinedBy' ):
155154 relations = entity .IsDefinedBy
156155 # p = {}
@@ -159,56 +158,57 @@ def entityToDict(self, entity, objData, parent=None):
159158 definition = rel .RelatingPropertyDefinition
160159 if definition .is_a () == 'IfcPropertySet' :
161160 relatedObjects = definition .HasProperties
162- for relatedObject in relatedObjects :
161+ for relatedObject in relatedObjects :
163162 value = relatedObject .NominalValue .wrappedValue
164163 if value and value != '' :
165- d [common .toLowerCamelcase (relatedObject .Name )] = value
164+ d [common .toLowerCamelcase (
165+ relatedObject .Name )] = value
166166 elif definition .is_a () == 'IfcElementQuantity' :
167167 relatedObjects = definition .Quantities
168- for relatedObject in relatedObjects :
168+ for relatedObject in relatedObjects :
169169 value = relatedObject .AreaValue
170170 if value and value != '' :
171- d [common .toLowerCamelcase (relatedObject .Name )] = value
171+ d [common .toLowerCamelcase (
172+ relatedObject .Name )] = value
172173 else :
173174 print ('Skipped: ' + str (definition ))
174175 else :
175176 print ('Skipped: ' + str (rel ))
176177 # if p:
177178 # d['properties'] = p
178-
179179
180180 if hasattr (entity , 'IsDecomposedBy' ):
181181 decomposedBy = entity .IsDecomposedBy
182182 invAtt = []
183183 for rel in decomposedBy :
184184 relatedObjects = rel .RelatedObjects
185- for relatedObject in relatedObjects :
186- relatedEntity = self .entityToDict (relatedObject , objData , parent = entity )
185+ for relatedObject in relatedObjects :
186+ relatedEntity = self .entityToDict (
187+ relatedObject , objData , parent = entity )
187188 if parent != relatedEntity :
188189 invAtt .append (relatedEntity )
189190 if invAtt :
190191 d ['IsDecomposedBy' ] = invAtt
191192
192-
193193 if hasattr (entity , 'ContainsElements' ):
194194 decomposedBy = entity .ContainsElements
195195 invAtt = []
196196 for rel in decomposedBy :
197197 relatedObjects = rel .RelatedElements
198- for relatedObject in relatedObjects :
199- relatedEntity = self .entityToDict (relatedObject , objData , parent = entity )
198+ for relatedObject in relatedObjects :
199+ relatedEntity = self .entityToDict (
200+ relatedObject , objData , parent = entity )
200201 if parent != relatedEntity :
201202 invAtt .append (relatedEntity )
202203 if invAtt :
203204 d ['ContainsElements' ] = invAtt
204205
205-
206206 if reference :
207207 uuid = guid .split (guid .expand (entityAttributes ["GlobalId" ]))[1 :- 1 ]
208208 ref ['ref' ] = uuid
209209 if not entityAttributes ['GlobalId' ] in self .id_objects :
210210
211- for i in range (0 ,len (entity )):
211+ for i in range (0 , len (entity )):
212212 attr = entity .attribute_name (i )
213213 attrKey = common .toLowerCamelcase (attr )
214214 if attr == "GlobalId" :
@@ -231,7 +231,8 @@ def entityToDict(self, entity, objData, parent=None):
231231 if attr == 'Representation' :
232232 if objData :
233233 if entityAttributes ['GlobalId' ] in objData :
234- id = guid .split (guid .expand (guid .new ()))[1 :- 1 ]
234+ id = guid .split (
235+ guid .expand (guid .new ()))[1 :- 1 ]
235236 d ['representations' ] = [
236237 {
237238 "type" : "shapeRepresentation" ,
@@ -251,23 +252,25 @@ def entityToDict(self, entity, objData, parent=None):
251252 else :
252253 continue
253254
254-
255255 # Skip ObjectPlacement: all OBJ geometries are in world coordinates
256256 if attr == 'ObjectPlacement' :
257257 continue
258258
259- jsonValue = self .getEntityValue (entityAttributes [attr ], objData )
259+ jsonValue = self .getEntityValue (
260+ entityAttributes [attr ], objData )
260261 if jsonValue :
261262 d [attrKey ] = jsonValue
262263 if entityAttributes [attr ] == None :
263264 continue
264265 elif isinstance (entityAttributes [attr ], ifcopenshell .entity_instance ):
265- d [attrKey ] = self .entityToDict (entityAttributes [attr ], objData )
266+ d [attrKey ] = self .entityToDict (
267+ entityAttributes [attr ], objData )
266268 elif isinstance (entityAttributes [attr ], tuple ):
267269 subEnts = []
268270 for subEntity in entityAttributes [attr ]:
269271 if isinstance (subEntity , ifcopenshell .entity_instance ):
270- subEntJson = self .entityToDict (subEntity , objData )
272+ subEntJson = self .entityToDict (
273+ subEntity , objData )
271274 if subEntJson :
272275 subEnts .append (subEntJson )
273276 else :
@@ -280,23 +283,26 @@ def entityToDict(self, entity, objData, parent=None):
280283 return ref
281284 else :
282285
283- for i in range (0 ,len (entity )):
286+ for i in range (0 , len (entity )):
284287 attr = entity .attribute_name (i )
285288 attrKey = common .toLowerCamelcase (attr )
286289 if attr in entityAttributes :
287290 if not attr == 'OwnerHistory' :
288- jsonValue = self .getEntityValue (entityAttributes [attr ], objData )
291+ jsonValue = self .getEntityValue (
292+ entityAttributes [attr ], objData )
289293 if jsonValue :
290294 d [attrKey ] = jsonValue
291295 if entityAttributes [attr ] == None :
292296 continue
293297 elif isinstance (entityAttributes [attr ], ifcopenshell .entity_instance ):
294- d [attrKey ] = self .entityToDict (entityAttributes [attr ], objData )
298+ d [attrKey ] = self .entityToDict (
299+ entityAttributes [attr ], objData )
295300 elif isinstance (entityAttributes [attr ], tuple ):
296301 subEnts = []
297302 for subEntity in entityAttributes [attr ]:
298303 if isinstance (subEntity , ifcopenshell .entity_instance ):
299- subEntJson = self .entityToDict (subEntity , objData )
304+ subEntJson = self .entityToDict (
305+ subEntity , objData )
300306 if subEntJson :
301307 subEnts .append (subEntJson )
302308 else :
@@ -306,7 +312,6 @@ def entityToDict(self, entity, objData, parent=None):
306312 else :
307313 d [attrKey ] = entityAttributes [attr ]
308314
309-
310315 return d
311316
312317 def getEntityValue (self , value , objData ):
@@ -327,7 +332,6 @@ def getEntityValue(self, value, objData):
327332 # convert IFC SPF file into OBJ using IfcConvert and extract OBJ objects
328333 def getObjData (self , ifcFilePath ):
329334 objFilePath = NamedTemporaryFile (suffix = '.obj' , delete = True ).name
330- print (objFilePath )
331335
332336 # Convert IFC to OBJ using IfcConvert (could also be done for glTF or Collada)
333337 subprocess .run ([
@@ -346,7 +350,7 @@ def getObjData(self, ifcFilePath):
346350 f = open (objFilePath , 'r' )
347351 lc = 0
348352 for line in f :
349- lc += 1
353+ lc += 1
350354
351355 # find group
352356 if line [0 ] == 'g' :
@@ -377,4 +381,4 @@ def getObjData(self, ifcFilePath):
377381 return objData
378382 else :
379383 print ('Creating intermediate OBJ failed' )
380- return None
384+ return None
0 commit comments