Esempio n. 1
0
 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)
Esempio n. 2
0
 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()
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 6
0
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