def getPoint(self, point=None, obj=None): "this function is called by the snapper when it has a 3D point" if obj: if Draft.getType(obj) == "Wall": if not obj in self.existing: self.existing.append(obj) if point == None: self.tracker.finalize() return self.points.append(point) if len(self.points) == 1: self.tracker.on() FreeCADGui.Snapper.getPoint(last=self.points[0], callback=self.getPoint, movecallback=self.update, extradlg=self.taskbox()) elif len(self.points) == 2: import Part add = False l = Part.Line(self.points[0], self.points[1]) self.tracker.finalize() FreeCAD.ActiveDocument.openTransaction("Wall") if not self.existing: self.addDefault(l) else: w = joinWalls(self.existing) if w: if areSameWallTypes([w, self]): w.Base.addGeometry(l) else: nw = self.addDefault(l) add = True else: self.addDefault(l) FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() if add: import ArchCommands ArchCommands.addComponents(nw, w)
def getPoint(self,point=None,obj=None): "this function is called by the snapper when it has a 3D point" if obj: if Draft.getType(obj) == "Wall": if not obj in self.existing: self.existing.append(obj) if point == None: self.tracker.finalize() return self.points.append(point) if len(self.points) == 1: self.tracker.on() FreeCADGui.Snapper.getPoint(last=self.points[0],callback=self.getPoint,movecallback=self.update,extradlg=self.taskbox()) elif len(self.points) == 2: import Part add = False l = Part.Line(self.points[0],self.points[1]) self.tracker.finalize() FreeCAD.ActiveDocument.openTransaction("Wall") if not self.existing: self.addDefault(l) else: w = joinWalls(self.existing) if w: if areSameWallTypes([w,self]): w.Base.addGeometry(l) else: nw = self.addDefault(l) add = True else: self.addDefault(l) FreeCAD.ActiveDocument.commitTransaction() FreeCAD.ActiveDocument.recompute() if add: import ArchCommands ArchCommands.addComponents(nw,w) if self.continueCmd: self.Activated()
def read(filename): "Parses an IFC file" # parsing the IFC file t1 = time.time() num_lines = sum(1 for line in pyopen(filename)) if getIfcOpenShell() and not FORCE_PYTHON_PARSER: # use the IfcOpenShell parser # preparing IfcOpenShell if DEBUG: global ifcObjects,ifcParents ifcObjects = {} # a table to relate ifc id with freecad object ifcParents = {} # a table to relate ifc id with parent id if hasattr(IfcImport,"DISABLE_OPENING_SUBTRACTIONS") and SEPARATE_OPENINGS: IfcImport.Settings(IfcImport.DISABLE_OPENING_SUBTRACTIONS,True) else: SKIP.append("IfcOpeningElement") useShapes = False if hasattr(IfcImport,"USE_BREP_DATA"): IfcImport.Settings(IfcImport.USE_BREP_DATA,True) useShapes = True else: if DEBUG: print "Warning: IfcOpenShell version very old, unable to handle Brep data" # processing geometry if IfcImport.Init(filename): while True: obj = IfcImport.Get() if DEBUG: print "["+str(int((float(obj.id)/num_lines)*100))+"%] parsing ",obj.id,": ",obj.name," of type ",obj.type # retrieving name n = getName(obj) # skip types if obj.type in SKIP: if DEBUG: print "skipping because type is in skip list" nobj = None else: # build shape shape = None if useShapes: shape = getShape(obj) # walls if obj.type in ["IfcWallStandardCase","IfcWall"]: nobj = makeWall(obj.id,shape,n) # windows elif obj.type in ["IfcWindow","IfcDoor"]: nobj = makeWindow(obj.id,shape,n) # structs elif obj.type in ["IfcBeam","IfcColumn","IfcSlab","IfcFooting"]: nobj = makeStructure(obj.id,shape,obj.type,n) # roofs elif obj.type in ["IfcRoof"]: nobj = makeRoof(obj.id,shape,n) # furniture elif obj.type in ["IfcFurnishingElement"]: nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n) nobj.Shape = shape # sites elif obj.type in ["IfcSite"]: nobj = makeSite(obj.id,shape,n) # spaces elif obj.type in ["IfcSpace"]: nobj = makeSpace(obj.id,shape,n) elif shape: # treat as dumb parts #if DEBUG: print "Fixme: Shape-containing object not handled: ",obj.id, " ", obj.type nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n) nobj.Shape = shape else: # treat as meshes if DEBUG: print "Warning: Object without shape: ",obj.id, " ", obj.type me,pl = getMesh(obj) nobj = FreeCAD.ActiveDocument.addObject("Mesh::Feature",n) nobj.Mesh = me nobj.Placement = pl # registering object number and parent if obj.parent_id > 0: ifcParents[obj.id] = [obj.parent_id,not (obj.type in subtractiveTypes)] ifcObjects[obj.id] = nobj if not IfcImport.Next(): break # processing non-geometry and relationships parents_temp = dict(ifcParents) import ArchCommands while parents_temp: id, c = parents_temp.popitem() parent_id = c[0] additive = c[1] if (id <= 0) or (parent_id <= 0): # root dummy object parent = None elif parent_id in ifcObjects: parent = ifcObjects[parent_id] # check if parent is a subtraction, if yes parent to grandparent if parent_id in ifcParents: if ifcParents[parent_id][1] == False: grandparent_id = ifcParents[parent_id][0] if grandparent_id in ifcObjects: parent = ifcObjects[grandparent_id] else: # creating parent if needed parent_ifcobj = IfcImport.GetObject(parent_id) if DEBUG: print "["+str(int((float(parent_ifcobj.id)/num_lines)*100))+"%] parsing ",parent_ifcobj.id,": ",parent_ifcobj.name," of type ",parent_ifcobj.type n = getName(parent_ifcobj) if parent_ifcobj.id <= 0: parent = None elif parent_ifcobj.type == "IfcBuildingStorey": parent = Arch.makeFloor(name=n) parent.Label = n elif parent_ifcobj.type == "IfcBuilding": parent = Arch.makeBuilding(name=n) parent.Label = n elif parent_ifcobj.type == "IfcSite": parent = Arch.makeSite(name=n) parent.Label = n elif parent_ifcobj.type == "IfcWindow": parent = Arch.makeWindow(name=n) parent.Label = n else: if DEBUG: print "Fixme: skipping unhandled parent: ", parent_ifcobj.id, " ", parent_ifcobj.type parent = None # registering object number and parent if parent_ifcobj.parent_id > 0: ifcParents[parent_ifcobj.id] = [parent_ifcobj.parent_id,True] parents_temp[parent_ifcobj.id] = [parent_ifcobj.parent_id,True] if parent and (not parent_ifcobj.id in ifcObjects): ifcObjects[parent_ifcobj.id] = parent # attributing parent if parent and (id in ifcObjects): if ifcObjects[id]: if additive: ArchCommands.addComponents(ifcObjects[id],parent) else: ArchCommands.removeComponents(ifcObjects[id],parent) IfcImport.CleanUp() else: # use only the internal python parser FreeCAD.Console.PrintWarning(str(translate("Arch","IfcOpenShell not found or disabled, falling back on internal parser.\n"))) schema=getSchema() if schema: if DEBUG: global ifc if DEBUG: print "opening",filename,"..." ifc = ifcReader.IfcDocument(filename,schema=schema,debug=DEBUG) else: FreeCAD.Console.PrintWarning(str(translate("Arch","IFC Schema not found, IFC import disabled.\n"))) return None t2 = time.time() if DEBUG: print "Successfully loaded",ifc,"in %s s" % ((t2-t1)) # getting walls for w in ifc.getEnt("IfcWallStandardCase"): nobj = makeWall(w) # getting windows and doors for w in (ifc.getEnt("IfcWindow") + ifc.getEnt("IfcDoor")): nobj = makeWindow(w) # getting structs for w in (ifc.getEnt("IfcSlab") + ifc.getEnt("IfcBeam") + ifc.getEnt("IfcColumn") \ + ifc.getEnt("IfcFooting")): nobj = makeStructure(w) # getting floors for f in ifc.getEnt("IfcBuildingStorey"): group(f,ifc,"Floor") # getting buildings for b in ifc.getEnt("IfcBuilding"): group(b,ifc,"Building") # getting sites for s in ifc.getEnt("IfcSite"): group(s,ifc,"Site") if DEBUG: print "done parsing. Recomputing..." FreeCAD.ActiveDocument.recompute() t3 = time.time() if DEBUG: print "done processing IFC file in %s s" % ((t3-t1)) return None
def read(filename): "Parses an IFC file" # parsing the IFC file t1 = time.time() num_lines = sum(1 for line in pyopen(filename)) if getIfcOpenShell() and not FORCE_PYTHON_PARSER: # use the IfcOpenShell parser # preparing IfcOpenShell if DEBUG: global ifcObjects, ifcParents ifcObjects = {} # a table to relate ifc id with freecad object ifcParents = {} # a table to relate ifc id with parent id if hasattr(IfcImport, "DISABLE_OPENING_SUBTRACTIONS") and SEPARATE_OPENINGS: IfcImport.Settings(IfcImport.DISABLE_OPENING_SUBTRACTIONS, True) else: SKIP.append("IfcOpeningElement") useShapes = False if hasattr(IfcImport, "USE_BREP_DATA"): IfcImport.Settings(IfcImport.USE_BREP_DATA, True) useShapes = True else: if DEBUG: print "Warning: IfcOpenShell version very old, unable to handle Brep data" # processing geometry if IfcImport.Init(filename): while True: obj = IfcImport.Get() if DEBUG: print "[" + str( int((float(obj.id) / num_lines) * 100) ) + "%] parsing ", obj.id, ": ", obj.name, " of type ", obj.type # retrieving name n = getName(obj) # skip types if obj.type in SKIP: if DEBUG: print "skipping because type is in skip list" nobj = None else: # build shape shape = None if useShapes: shape = getShape(obj) # walls if obj.type in ["IfcWallStandardCase", "IfcWall"]: nobj = makeWall(obj.id, shape, n) # windows elif obj.type in ["IfcWindow", "IfcDoor"]: nobj = makeWindow(obj.id, shape, n) # structs elif obj.type in [ "IfcBeam", "IfcColumn", "IfcSlab", "IfcFooting" ]: nobj = makeStructure(obj.id, shape, n) # roofs elif obj.type in ["IfcRoof"]: nobj = makeRoof(obj.id, shape, n) # furniture elif obj.type in ["IfcFurnishingElement"]: nobj = FreeCAD.ActiveDocument.addObject( "Part::Feature", n) nobj.Shape = shape # sites elif obj.type in ["IfcSite"]: nobj = makeSite(obj.id, shape, n) # spaces elif obj.type in ["IfcSpace"]: nobj = makeSpace(obj.id, shape, n) elif shape: # treat as dumb parts #if DEBUG: print "Fixme: Shape-containing object not handled: ",obj.id, " ", obj.type nobj = FreeCAD.ActiveDocument.addObject( "Part::Feature", n) nobj.Shape = shape else: # treat as meshes if DEBUG: print "Warning: Object without shape: ", obj.id, " ", obj.type me, pl = getMesh(obj) nobj = FreeCAD.ActiveDocument.addObject( "Mesh::Feature", n) nobj.Mesh = me nobj.Placement = pl # registering object number and parent if obj.parent_id > 0: ifcParents[obj.id] = [ obj.parent_id, not (obj.type in subtractiveTypes) ] ifcObjects[obj.id] = nobj if not IfcImport.Next(): break # processing non-geometry and relationships parents_temp = dict(ifcParents) import ArchCommands while parents_temp: id, c = parents_temp.popitem() parent_id = c[0] additive = c[1] if (id <= 0) or (parent_id <= 0): # root dummy object parent = None elif parent_id in ifcObjects: parent = ifcObjects[parent_id] # check if parent is a subtraction, if yes parent to grandparent if parent_id in ifcParents: if ifcParents[parent_id][1] == False: grandparent_id = ifcParents[parent_id][0] if grandparent_id in ifcObjects: parent = ifcObjects[grandparent_id] else: # creating parent if needed parent_ifcobj = IfcImport.GetObject(parent_id) if DEBUG: print "[" + str( int((float(parent_ifcobj.id) / num_lines) * 100) ) + "%] parsing ", parent_ifcobj.id, ": ", parent_ifcobj.name, " of type ", parent_ifcobj.type n = getName(parent_ifcobj) if parent_ifcobj.id <= 0: parent = None elif parent_ifcobj.type == "IfcBuildingStorey": parent = Arch.makeFloor(name=n) elif parent_ifcobj.type == "IfcBuilding": parent = Arch.makeBuilding(name=n) elif parent_ifcobj.type == "IfcSite": parent = Arch.makeSite(name=n) elif parent_ifcobj.type == "IfcWindow": parent = Arch.makeWindow(name=n) else: if DEBUG: print "Fixme: skipping unhandled parent: ", parent_ifcobj.id, " ", parent_ifcobj.type parent = None # registering object number and parent if parent_ifcobj.parent_id > 0: ifcParents[parent_ifcobj.id] = [ parent_ifcobj.parent_id, True ] parents_temp[parent_ifcobj.id] = [ parent_ifcobj.parent_id, True ] if parent and (not parent_ifcobj.id in ifcObjects): ifcObjects[parent_ifcobj.id] = parent # attributing parent if parent and (id in ifcObjects): if ifcObjects[id]: if additive: ArchCommands.addComponents(ifcObjects[id], parent) else: ArchCommands.removeComponents(ifcObjects[id], parent) IfcImport.CleanUp() else: # use only the internal python parser FreeCAD.Console.PrintWarning( str( translate( "Arch", "IfcOpenShell not found, falling back on internal parser.\n" ))) schema = getSchema() if schema: if DEBUG: global ifc if DEBUG: print "opening", filename, "..." ifc = ifcReader.IfcDocument(filename, schema=schema, debug=DEBUG) else: FreeCAD.Console.PrintWarning( str( translate("Arch", "IFC Schema not found, IFC import disabled.\n"))) return None t2 = time.time() if DEBUG: print "Successfully loaded", ifc, "in %s s" % ((t2 - t1)) # getting walls for w in ifc.getEnt("IfcWallStandardCase"): nobj = makeWall(w) # getting windows and doors for w in (ifc.getEnt("IfcWindow") + ifc.getEnt("IfcDoor")): nobj = makeWindow(w) # getting structs for w in (ifc.getEnt("IfcSlab") + ifc.getEnt("IfcBeam") + ifc.getEnt("IfcColumn") \ + ifc.getEnt("IfcFooting")): nobj = makeStructure(w) # getting floors for f in ifc.getEnt("IfcBuildingStorey"): group(f, ifc, "Floor") # getting buildings for b in ifc.getEnt("IfcBuilding"): group(b, ifc, "Building") # getting sites for s in ifc.getEnt("IfcSite"): group(s, ifc, "Site") if DEBUG: print "done parsing. Recomputing..." FreeCAD.ActiveDocument.recompute() t3 = time.time() if DEBUG: print "done processing IFC file in %s s" % ((t3 - t1)) return None
def read(filename): "Parses an IFC file" # parsing the IFC file t1 = time.time() processedIds = [] if getIfcOpenShell() and not FORCE_PYTHON_PARSER: # use the IfcOpenShell parser # check for IFcOpenShellVersion global IOC_ADVANCED if hasattr(IfcImport,"IfcFile"): IOC_ADVANCED = True else: IOC_ADVANCED = False # preparing IfcOpenShell if DEBUG: global ifcObjects,ifcParents ifcObjects = {} # a table to relate ifc id with freecad object ifcParents = {} # a table to relate ifc id with parent id if SEPARATE_OPENINGS: if hasattr(IfcImport,"DISABLE_OPENING_SUBTRACTIONS"): IfcImport.Settings(IfcImport.DISABLE_OPENING_SUBTRACTIONS,True) else: SKIP.append("IfcOpeningElement") useShapes = False if IOC_ADVANCED: useShapes = True elif hasattr(IfcImport,"USE_BREP_DATA"): IfcImport.Settings(IfcImport.USE_BREP_DATA,True) useShapes = True else: if DEBUG: print "Warning: IfcOpenShell version very old, unable to handle Brep data" # opening file if IOC_ADVANCED: global ifc ifc = IfcImport.open(filename) objects = ifc.by_type("IfcProduct") num_lines = len(objects) relations = ifc.by_type("IfcRelAggregates") + ifc.by_type("IfcRelContainedInSpatialStructure") + ifc.by_type("IfcRelVoidsElement") if not objects: print "Error opening IFC file" return else: num_lines = sum(1 for line in pyopen(filename)) if not IfcImport.Init(filename): print "Error opening IFC file" return # processing geometry idx = 0 while True: if IOC_ADVANCED: obj = objects[idx] idx += 1 objid = int(str(obj).split("=")[0].strip("#")) objname = obj.get_argument(obj.get_argument_index("Name")) objtype = str(obj).split("=")[1].split("(")[0] objparentid = -1 for r in relations: if r.is_a("IfcRelAggregates"): for c in getAttr(r,"RelatedObjects"): if str(obj) == str(c): objparentid = int(str(getAttr(r,"RelatingObject")).split("=")[0].strip("#")) elif r.is_a("IfcRelContainedInSpatialStructure"): for c in getAttr(r,"RelatedElements"): if str(obj) == str(c): objparentid = int(str(getAttr(r,"RelatingStructure")).split("=")[0].strip("#")) elif r.is_a("IfcRelVoidsElement"): if str(obj) == str(getAttr(r,"RelatedOpeningElement")): objparentid = int(str(getAttr(r,"RelatingBuildingElement")).split("=")[0].strip("#")) else: if hasattr(IfcImport, 'GetBrepData'): obj = IfcImport.GetBrepData() else: obj = IfcImport.Get() objid = obj.id idx = objid objname = obj.name objtype = obj.type objparentid = obj.parent_id if DEBUG: print "["+str(int((float(idx)/num_lines)*100))+"%] parsing ",objid,": ",objname," of type ",objtype # retrieving name n = getCleanName(objname,objid,objtype) # skip types if objtype in SKIP: if DEBUG: print "skipping because type is in skip list" nobj = None # check if object was already processed, to workaround an ifcopenshell bug elif objid in processedIds: if DEBUG: print "skipping because this object was already processed" else: # build shape shape = None if useShapes: shape = getShape(obj,objid) # walls if objtype in ["IfcWallStandardCase","IfcWall"]: nobj = makeWall(objid,shape,n) # windows elif objtype in ["IfcWindow","IfcDoor"]: nobj = makeWindow(objid,shape,n) # structs elif objtype in ["IfcBeam","IfcColumn","IfcSlab","IfcFooting"]: nobj = makeStructure(objid,shape,objtype,n) # roofs elif objtype in ["IfcRoof"]: nobj = makeRoof(objid,shape,n) # furniture elif objtype in ["IfcFurnishingElement"]: nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n) nobj.Shape = shape # sites elif objtype in ["IfcSite"]: nobj = makeSite(objid,shape,n) # floors elif objtype in ["IfcBuildingStorey"]: nobj = Arch.makeFloor(name=n) nobj.Label = n # floors elif objtype in ["IfcBuilding"]: nobj = Arch.makeBuilding(name=n) nobj.Label = n # spaces elif objtype in ["IfcSpace"]: nobj = makeSpace(objid,shape,n) elif shape: # treat as dumb parts #if DEBUG: print "Fixme: Shape-containing object not handled: ",obj.id, " ", obj.type nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n) nobj.Label = n nobj.Shape = shape else: # treat as meshes if DEBUG: print "Warning: Object without shape: ",objid, " ", objtype if hasattr(obj,"mesh"): if not hasattr(obj.mesh, 'verts'): obj = IfcImport.Get() # Get triangulated rep of same product me,pl = getMesh(obj) nobj = FreeCAD.ActiveDocument.addObject("Mesh::Feature",n) nobj.Label = n nobj.Mesh = me nobj.Placement = pl else: if DEBUG: print "Error: Skipping object without mesh: ",objid, " ", objtype # registering object number and parent if objparentid > 0: ifcParents[objid] = [objparentid,not (objtype in subtractiveTypes)] ifcObjects[objid] = nobj processedIds.append(objid) if IOC_ADVANCED: if idx >= len(objects): break else: if not IfcImport.Next(): break # processing non-geometry and relationships parents_temp = dict(ifcParents) import ArchCommands #print parents_temp while parents_temp: id, c = parents_temp.popitem() parent_id = c[0] additive = c[1] if (id <= 0) or (parent_id <= 0): # root dummy object parent = None elif parent_id in ifcObjects: parent = ifcObjects[parent_id] # check if parent is a subtraction, if yes parent to grandparent if parent_id in ifcParents: if ifcParents[parent_id][1] == False: grandparent_id = ifcParents[parent_id][0] if grandparent_id in ifcObjects: parent = ifcObjects[grandparent_id] else: # creating parent if needed if IOC_ADVANCED: parent_ifcobj = ifc.by_id(parent_id) parentid = int(str(obj).split("=")[0].strip("#")) parentname = obj.get_argument(obj.get_argument_index("Name")) parenttype = str(obj).split("=")[1].split("(")[0] else: parent_ifcobj = IfcImport.GetObject(parent_id) parentid = obj.id parentname = obj.name parenttype = obj.type #if DEBUG: print "["+str(int((float(idx)/num_lines)*100))+"%] parsing ",parentid,": ",parentname," of type ",parenttype n = getCleanName(parentname,parentid,parenttype) if parentid <= 0: parent = None elif parenttype == "IfcBuildingStorey": parent = Arch.makeFloor(name=n) parent.Label = n elif parenttype == "IfcBuilding": parent = Arch.makeBuilding(name=n) parent.Label = n elif parenttype == "IfcSite": parent = Arch.makeSite(name=n) parent.Label = n elif parenttype == "IfcWindow": parent = Arch.makeWindow(name=n) parent.Label = n else: if DEBUG: print "Fixme: skipping unhandled parent: ", parentid, " ", parenttype parent = None # registering object number and parent if not IOC_ADVANCED: if parent_ifcobj.parent_id > 0: ifcParents[parentid] = [parent_ifcobj.parent_id,True] parents_temp[parentid] = [parent_ifcobj.parent_id,True] if parent and (not parentid in ifcObjects): ifcObjects[parentid] = parent # attributing parent if parent and (id in ifcObjects): if ifcObjects[id] and (ifcObjects[id].Name != parent.Name): if additive: if DEBUG: print "adding ",ifcObjects[id].Name, " to ",parent.Name ArchCommands.addComponents(ifcObjects[id],parent) else: if DEBUG: print "removing ",ifcObjects[id].Name, " from ",parent.Name ArchCommands.removeComponents(ifcObjects[id],parent) if not IOC_ADVANCED: IfcImport.CleanUp() else: # use only the internal python parser FreeCAD.Console.PrintWarning(translate("Arch","IfcOpenShell not found or disabled, falling back on internal parser.\n")) schema=getSchema() if schema: if DEBUG: print "opening",filename,"..." ifc = ifcReader.IfcDocument(filename,schema=schema,debug=DEBUG) else: FreeCAD.Console.PrintWarning(translate("Arch","IFC Schema not found, IFC import disabled.\n")) return None t2 = time.time() if DEBUG: print "Successfully loaded",ifc,"in %s s" % ((t2-t1)) # getting walls for w in ifc.getEnt("IfcWallStandardCase"): nobj = makeWall(w) # getting windows and doors for w in (ifc.getEnt("IfcWindow") + ifc.getEnt("IfcDoor")): nobj = makeWindow(w) # getting structs for w in (ifc.getEnt("IfcSlab") + ifc.getEnt("IfcBeam") + ifc.getEnt("IfcColumn") \ + ifc.getEnt("IfcFooting")): nobj = makeStructure(w) # getting floors for f in ifc.getEnt("IfcBuildingStorey"): group(f,ifc,"Floor") # getting buildings for b in ifc.getEnt("IfcBuilding"): group(b,ifc,"Building") # getting sites for s in ifc.getEnt("IfcSite"): group(s,ifc,"Site") if DEBUG: print "done parsing. Recomputing..." FreeCAD.ActiveDocument.recompute() t3 = time.time() if DEBUG: print "done processing IFC file in %s s" % ((t3-t1)) return None
def read(filename,skip=None): "Parses an IFC file" # parsing the IFC file t1 = time.time() processedIds = [] skipIds = skip if not skipIds: skipIds = [] elif isinstance(skipIds,int): skipIds = [skipIds] if getIfcOpenShell() and not FORCE_PYTHON_PARSER: # use the IfcOpenShell parser # check for IFcOpenShellVersion global IFCOPENSHELL5 if hasattr(IfcImport,"IfcFile"): IFCOPENSHELL5 = True else: IFCOPENSHELL5 = False # preparing IfcOpenShell if DEBUG: global ifcObjects,ifcParents ifcObjects = {} # a table to relate ifc id with freecad object ifcParents = {} # a table to relate ifc id with parent id if SEPARATE_OPENINGS: if not IFCOPENSHELL5: if hasattr(IfcImport,"DISABLE_OPENING_SUBTRACTIONS"): IfcImport.Settings(IfcImport.DISABLE_OPENING_SUBTRACTIONS,True) else: SKIP.append("IfcOpeningElement") useShapes = False if IFCOPENSHELL5: useShapes = True if hasattr(IfcImport,"clean"): IfcImport.clean() elif hasattr(IfcImport,"USE_BREP_DATA"): IfcImport.Settings(IfcImport.USE_BREP_DATA,True) useShapes = True else: if DEBUG: print "Warning: IfcOpenShell version very old, unable to handle Brep data" # opening file if IFCOPENSHELL5: global ifc ifc = IfcImport.open(filename) objects = ifc.by_type("IfcProduct") num_lines = len(objects) relations = ifc.by_type("IfcRelAggregates") + ifc.by_type("IfcRelContainedInSpatialStructure") + ifc.by_type("IfcRelVoidsElement") if not objects: print "Error opening IFC file" return else: num_lines = sum(1 for line in pyopen(filename)) if not IfcImport.Init(filename): print "Error opening IFC file" return # processing geometry idx = 0 while True: objparentid = [] if IFCOPENSHELL5: obj = objects[idx] idx += 1 objid = int(str(obj).split("=")[0].strip("#")) objname = obj.get_argument(obj.get_argument_index("Name")) objtype = str(obj).split("=")[1].split("(")[0] for r in relations: if r.is_a("IfcRelAggregates"): for c in getAttr(r,"RelatedObjects"): if str(obj) == str(c): objparentid.append(int(str(getAttr(r,"RelatingObject")).split("=")[0].strip("#"))) elif r.is_a("IfcRelContainedInSpatialStructure"): for c in getAttr(r,"RelatedElements"): if str(obj) == str(c): objparentid.append(int(str(getAttr(r,"RelatingStructure")).split("=")[0].strip("#"))) elif r.is_a("IfcRelVoidsElement"): if str(obj) == str(getAttr(r,"RelatedOpeningElement")): objparentid.append(int(str(getAttr(r,"RelatingBuildingElement")).split("=")[0].strip("#"))) else: if hasattr(IfcImport, 'GetBrepData'): obj = IfcImport.GetBrepData() else: obj = IfcImport.Get() objid = obj.id idx = objid objname = obj.name objtype = obj.type objparentid.append(obj.parent_id) if DEBUG: print "["+str(int((float(idx)/num_lines)*100))+"%] parsing ",objid,": ",objname," of type ",objtype # retrieving name n = getCleanName(objname,objid,objtype) # skip IDs if objid in skipIds: if DEBUG: print " skipping because object ID is in skip list" nobj = None # skip types elif objtype in SKIP: if DEBUG: print " skipping because type is in skip list" nobj = None # check if object was already processed, to workaround an ifcopenshell bug elif objid in processedIds: if DEBUG: print " skipping because this object was already processed" else: # build shape shape = None if useShapes: shape = getShape(obj,objid) # walls if objtype in ["IfcWallStandardCase","IfcWall"]: nobj = makeWall(objid,shape,n) # windows elif objtype in ["IfcWindow","IfcDoor"]: nobj = makeWindow(objid,shape,n) # structs elif objtype in ["IfcBeam","IfcColumn","IfcSlab","IfcFooting"]: nobj = makeStructure(objid,shape,objtype,n) # roofs elif objtype in ["IfcRoof"]: nobj = makeRoof(objid,shape,n) # furniture elif objtype in ["IfcFurnishingElement"]: nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n) nobj.Shape = shape # sites elif objtype in ["IfcSite"]: nobj = makeSite(objid,shape,n) # floors elif objtype in ["IfcBuildingStorey"]: nobj = Arch.makeFloor(name=n) nobj.Label = n # floors elif objtype in ["IfcBuilding"]: nobj = Arch.makeBuilding(name=n) nobj.Label = n # spaces elif objtype in ["IfcSpace"]: nobj = makeSpace(objid,shape,n) elif shape: # treat as dumb parts if DEBUG: print "Fixme: Shape-containing object not handled: ",objid, " ", objtype nobj = FreeCAD.ActiveDocument.addObject("Part::Feature",n) nobj.Label = n nobj.Shape = shape else: # treat as meshes if DEBUG: print "Warning: Object without shape: ",objid, " ", objtype if hasattr(obj,"mesh"): if not hasattr(obj.mesh, 'verts'): obj = IfcImport.Get() # Get triangulated rep of same product me,pl = getMesh(obj) nobj = FreeCAD.ActiveDocument.addObject("Mesh::Feature",n) nobj.Label = n nobj.Mesh = me nobj.Placement = pl else: if DEBUG: print "Error: Skipping object without mesh: ",objid, " ", objtype # registering object number and parent if objparentid: ifcParents[objid] = [] for p in objparentid: ifcParents[objid].append([p,not (objtype in subtractiveTypes)]) ifcObjects[objid] = nobj processedIds.append(objid) if IFCOPENSHELL5: if idx >= len(objects): break else: if not IfcImport.Next(): break # processing non-geometry and relationships parents_temp = dict(ifcParents) import ArchCommands #print parents_temp while parents_temp: id, comps = parents_temp.popitem() for c in comps: parent_id = c[0] additive = c[1] if (id <= 0) or (parent_id <= 0): # root dummy object parent = None elif parent_id in ifcObjects: parent = ifcObjects[parent_id] # check if parent is a subtraction, if yes parent to grandparent if parent_id in ifcParents: for p in ifcParents[parent_id]: if p[1] == False: grandparent_id = p[0] if grandparent_id in ifcObjects: parent = ifcObjects[grandparent_id] else: # creating parent if needed if IFCOPENSHELL5: obj = ifc.by_id(parent_id) parentid = int(str(obj).split("=")[0].strip("#")) parentname = obj.get_argument(obj.get_argument_index("Name")) parenttype = str(obj).split("=")[1].split("(")[0] else: obj = IfcImport.GetObject(parent_id) parentid = obj.id parentname = obj.name parenttype = obj.type #if DEBUG: print "["+str(int((float(idx)/num_lines)*100))+"%] parsing ",parentid,": ",parentname," of type ",parenttype n = getCleanName(parentname,parentid,parenttype) if parentid <= 0: parent = None elif parenttype == "IfcBuildingStorey": parent = Arch.makeFloor(name=n) parent.Label = n elif parenttype == "IfcBuilding": parent = Arch.makeBuilding(name=n) parent.Label = n elif parenttype == "IfcSite": parent = Arch.makeSite(name=n) parent.Label = n elif parenttype == "IfcWindow": parent = Arch.makeWindow(name=n) parent.Label = n elif parenttype == "IfcProject": parent = None else: if DEBUG: print "Fixme: skipping unhandled parent: ", parentid, " ", parenttype parent = None # registering object number and parent if not IFCOPENSHELL5: if parent_ifcobj.parent_id > 0: ifcParents[parentid] = [parent_ifcobj.parent_id,True] parents_temp[parentid] = [parent_ifcobj.parent_id,True] if parent and (not parentid in ifcObjects): ifcObjects[parentid] = parent # attributing parent if parent and (id in ifcObjects): if ifcObjects[id] and (ifcObjects[id].Name != parent.Name): if additive: if DEBUG: print "adding ",ifcObjects[id].Name, " to ",parent.Name ArchCommands.addComponents(ifcObjects[id],parent) else: if DEBUG: print "removing ",ifcObjects[id].Name, " from ",parent.Name ArchCommands.removeComponents(ifcObjects[id],parent) if not IFCOPENSHELL5: IfcImport.CleanUp() else: # use only the internal python parser FreeCAD.Console.PrintWarning(translate("Arch","IfcOpenShell not found or disabled, falling back on internal parser.\n")) schema=getSchema() if schema: if DEBUG: print "opening",filename,"..." ifcReader.DEBUG = DEBUG ifc = ifcReader.IfcDocument(filename,schema=schema) else: FreeCAD.Console.PrintWarning(translate("Arch","IFC Schema not found, IFC import disabled.\n")) return None t2 = time.time() if DEBUG: print "Successfully loaded",ifc,"in %s s" % ((t2-t1)) # getting walls for w in ifc.getEnt("IfcWallStandardCase"): nobj = makeWall(w) # getting windows and doors for w in (ifc.getEnt("IfcWindow") + ifc.getEnt("IfcDoor")): nobj = makeWindow(w) # getting structs for w in (ifc.getEnt("IfcSlab") + ifc.getEnt("IfcBeam") + ifc.getEnt("IfcColumn") \ + ifc.getEnt("IfcFooting")): nobj = makeStructure(w) # getting floors for f in ifc.getEnt("IfcBuildingStorey"): group(f,ifc,"Floor") # getting buildings for b in ifc.getEnt("IfcBuilding"): group(b,ifc,"Building") # getting sites for s in ifc.getEnt("IfcSite"): group(s,ifc,"Site") if DEBUG: print "done parsing. Recomputing..." FreeCAD.ActiveDocument.recompute() t3 = time.time() if DEBUG: print "done processing IFC file in %s s" % ((t3-t1)) return None