예제 #1
0
 def addProduct(self,elttype,shapes,storey=None,placement=None,name="Unnamed element",description=None,extra=None):
     """addProduct(elttype,representations,[storey,placement,name,description,extra]): creates an element of the given type
     (IfcWall, IfcBeam, etc...) with the given attributes, plus the given extra attributes."""
     elttype = str(elttype)
     if not extra:
         extra = []
     if not description:
         description = None
     if not placement:
         placement = self.addPlacement()
     representations = self.addRepresentations(shapes)
     prd = create(self._fileobject,"IfcProductDefinitionShape",[None,None,representations])
     try:
         elt = create(self._fileobject,elttype,[uid(),self._owner,name,description,None,placement,prd,None]+extra)
     except:
         print "unable to create an ",elttype, " with attributes: ",[uid(),self._owner,str(name),description,None,placement,prd,None]+extra
         try:
             if hasattr(ifcw,"Entity"):
                 o = ifcw.Entity(elttype)
             else:
                 o = ifcw.entity_instance(elttype)
             print "supported attributes are: "
             print getPropertyNames(o)
         except:
             print "unable to create an element of type '"+elttype+"'"
         print "WARNING: skipping object '"+name+"' of type "+elttype
         return None
     self.BuildingProducts.append(elt)
     if not storey:
         if self.Storeys:
             storey = self.Storeys[0]
         else:
             storey = self.addStorey()
     self._relate(storey,elt)
     return elt
예제 #2
0
 def __init__(self,filepath="",name="",owner="",organization="",application="Python IFC exporter",version="0.0"):
     if hasattr(ifcw,"IfcFile"):
         self._fileobject = ifcw.IfcFile()
     else:
         self._fileobject = ifcw.file()
     self._person = create(self._fileobject,"IfcPerson",[None,None,"",None,None,None,None,None])
     self._org = create(self._fileobject,"IfcOrganization",[None,"",None,None,None])
     pno = create(self._fileobject,"IfcPersonAndOrganization",[self._person,self._org,None])
     app = create(self._fileobject,"IfcApplication",[self._org,version,application,uid()])
     self._owner = create(self._fileobject,"IfcOwnerHistory",[pno,app,None,"ADDED",None,pno,app,now()])
     axp = self.addPlacement(local=False)
     dim0 = create(self._fileobject,"IfcDirection",getTuple((0,1,0)))
     self._repcontext = create(self._fileobject,"IfcGeometricRepresentationContext",['Plan','Model',3,1.E-05,axp,dim0])
     dim1 = create(self._fileobject,"IfcDimensionalExponents",[0,0,0,0,0,0,0])
     dim2 = create(self._fileobject,"IfcSIUnit",[dim1,"LENGTHUNIT","MILLI","METRE"])
     dim3 = create(self._fileobject,"IfcSIUnit",[dim1,"AREAUNIT",None,"SQUARE_METRE"])
     dim4 = create(self._fileobject,"IfcSIUnit",[dim1,"VOLUMEUNIT",None,"CUBIC_METRE"])
     dim6 = create(self._fileobject,"IfcSIUnit",[dim1,"PLANEANGLEUNIT",None,"RADIAN"])
     dim7 = create(None,"IfcPlaneAngleMeasure",[1.745E-2])
     dim8 = create(self._fileobject,"IfcMeasureWithUnit",[dim7,dim6])
     dim9 = create(self._fileobject,"IfcConversionBasedUnit",[dim1,"PLANEANGLEUNIT","DEGREE",dim8])
     units = create(self._fileobject,"IfcUnitAssignment",[[dim2,dim3,dim4,dim9]])
     self.Project = create(self._fileobject,"IfcProject",[uid(),self._owner,None,None,None,None,None,[self._repcontext],units])
     self.Site = None
     self._storeyRelations = {}
     self.BuildingProducts = []
     self.Storeys = []
     self.Buildings = []
     self.FilePath = filepath
     self.Owner = owner
     self.Organization = organization
     self.Name = name
예제 #3
0
def readOpenShell(filename, useParser=False):
    "Parses an IFC file with IfcOpenShell"

    altifc = None
    if useParser:
        altifc = parseFile(filename)

    if getIfcOpenShell():
        USESHAPES = False
        if hasattr(IfcImport, "USE_BREP_DATA"):
            IfcImport.Settings(IfcImport.USE_BREP_DATA, True)
            USESHAPES = True
        if IfcImport.Init(filename):
            while True:

                obj = IfcImport.Get()
                if DEBUG:
                    print "parsing ", obj.id, ": ", obj.name, " of type ", obj.type
                meshdata = []
                n = obj.name
                if not n: n = "Unnamed"

                if obj.type in SKIP:
                    pass

                elif altifc and (obj.type == "IfcWallStandardCase"):
                    if USESHAPES:
                        makeWall(altifc.Entities[obj.id], shape=getShape(obj))
                    else:
                        makeWall(altifc.Entities[obj.id])

                elif USESHAPES:
                    # treat as Parts
                    sh = getShape(obj)
                    nobj = FreeCAD.ActiveDocument.addObject("Part::Feature", n)
                    nobj.Shape = sh
                else:
                    # treat as meshes
                    me, pl = getMesh(obj)
                    nobj = FreeCAD.ActiveDocument.addObject("Mesh::Feature", n)
                    nobj.Mesh = me
                    nobj.Placement = pl

                if not IfcImport.Next():
                    break
    IfcImport.CleanUp()
    return None
예제 #4
0
def create(ifcdoc=None,ifcname=None,arguments=[]):
    """create(ifcdoc,ifcname,[arguments]):creates an entity 
    of the given name in the given document and optionally 
    gives it an ordered list of arguments"""
    entity = IfcImport.Entity(ifcname)
    if ifcdoc:
        ifcdoc.add(entity)
    # this is a temporary hack while ifcopenshell has no ref counting
    holder.refs.append(entity)
    if not isinstance(arguments,list):
        arguments = [arguments]
    for i in range(len(arguments)):
        arg = arguments[i]
        if isinstance(arg,tuple):
            if len(arg) in [2,3]:
                arg = IfcImport.Doubles(arg)
        entity.set_argument(i,arg)
    return entity
예제 #5
0
def getShape(obj,objid):
    "gets a shape from an IfcOpenShell object"
    #print "retrieving shape from obj ",objid
    import Part
    sh=Part.Shape()
    brep_data = None
    if IFCOPENSHELL5:
        try:
            brep_data = IfcImport.create_shape(obj)
        except:
            print "Unable to retrieve shape data"
    else:
        brep_data = obj.mesh.brep_data
    if brep_data:
        try:
            if MAKETEMPFILES:
                import tempfile
                tf = tempfile.mkstemp(suffix=".brp")[1]
                of = pyopen(tf,"wb")
                of.write(brep_data)
                of.close()
                sh = Part.read(tf)
                os.remove(tf)
            else:
                sh.importBrepFromString(brep_data)
        except:
            print "Error: malformed shape"
            return None
        else:
            if IFCOPENSHELL5 and ADDPLACEMENT:
                sh.Placement = getPlacement(getAttr(obj,"ObjectPlacement"))
    if not sh.Solids:
        # try to extract a solid shape
        if sh.Faces:
            try:
                if DEBUG: print "Malformed solid. Attempting to fix..."
                shell = Part.makeShell(sh.Faces)
                if shell:
                    solid = Part.makeSolid(shell)
                    if solid:
                        sh = solid
            except:
                if DEBUG: print "failed to retrieve solid from object ",objid
        else:
            if DEBUG: print "object ", objid, " doesn't contain any geometry"
    if not IFCOPENSHELL5:
        m = obj.matrix
        mat = FreeCAD.Matrix(m[0], m[3], m[6], m[9],
                             m[1], m[4], m[7], m[10],
                             m[2], m[5], m[8], m[11],
                             0, 0, 0, 1)
        sh.Placement = FreeCAD.Placement(mat)
    # if DEBUG: print "getting Shape from ",obj 
    #print "getting shape: ",sh,sh.Solids,sh.Volume,sh.isValid(),sh.isNull()
    #for v in sh.Vertexes: print v.Point
    return sh
예제 #6
0
def getShape(obj,objid):
    "gets a shape from an IfcOpenShell object"
    #print "retrieving shape from obj ",objid
    import Part
    sh=Part.Shape()
    brep_data = None
    if IOC_ADVANCED:
        try:
            brep_data = IfcImport.create_shape(obj)
        except:
            print "Unable to retrieve shape data"
    else:
        brep_data = obj.mesh.brep_data
    if brep_data:
        try:
            if MAKETEMPFILES:
                import tempfile
                tf = tempfile.mkstemp(suffix=".brp")[1]
                of = pyopen(tf,"wb")
                of.write(brep_data)
                of.close()
                sh = Part.read(tf)
                os.remove(tf)
            else:
                sh.importBrepFromString(brep_data)
        except:
            print "Error: malformed shape"
            return None
    if not sh.Solids:
        # try to extract a solid shape
        if sh.Faces:
            try:
                if DEBUG: print "Malformed solid. Attempting to fix..."
                shell = Part.makeShell(sh.Faces)
                if shell:
                    solid = Part.makeSolid(shell)
                    if solid:
                        sh = solid
            except:
                if DEBUG: print "failed to retrieve solid from object ",objid
        else:
            if DEBUG: print "object ", objid, " doesn't contain any geometry"
    if not IOC_ADVANCED:
        m = obj.matrix
        mat = FreeCAD.Matrix(m[0], m[3], m[6], m[9],
                             m[1], m[4], m[7], m[10],
                             m[2], m[5], m[8], m[11],
                             0, 0, 0, 1)
        sh.Placement = FreeCAD.Placement(mat)
    # if DEBUG: print "getting Shape from ",obj 
    #print "getting shape: ",sh,sh.Solids,sh.Volume,sh.isValid(),sh.isNull()
    #for v in sh.Vertexes: print v.Point
    return sh
예제 #7
0
def create(ifcdoc=None,ifcname=None,arguments=[]):
    """create(ifcdoc,ifcname,[arguments]):creates an entity 
    of the given name in the given document and optionally 
    gives it an ordered list of arguments"""
    if hasattr(ifcw,"Entity"):
        entity = ifcw.Entity(ifcname)
    else:
        entity = ifcw.entity_instance(ifcname)
    if ifcdoc:
        ifcdoc.add(entity)
    # this is a temporary hack while ifcopenshell has no ref counting
    holder.refs.append(entity)
    if not isinstance(arguments,list):
        arguments = [arguments]
    for i in range(len(arguments)):
        arg = arguments[i]
        if isinstance(arg,tuple):
            if len(arg) in [2,3]:
                if hasattr(ifcw,"Doubles"):
                    arg = ifcw.Doubles(arg)
                else:
                    arg = ifcw.doubles(arg)
        entity.set_argument(i,arg)
    return entity
예제 #8
0
def new():
    """new(): returns a new empty ifc file holder"""
    fil = IfcImport.IfcFile()
    return fil
예제 #9
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
예제 #10
0
def read(filename):
    "Parses an IFC file"

    # parsing the IFC file
    t1 = time.time()
    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))

    if useIfcOpenShell and getIfcOpenShell():
        # use the IfcOpenShell parser

        useShapes = False
        if hasattr(IfcImport, "USE_BREP_DATA"):
            IfcImport.Settings(IfcImport.USE_BREP_DATA, True)
            useShapes = True
        if IfcImport.Init(filename):
            while True:

                obj = IfcImport.Get()
                if DEBUG:
                    print "parsing ", obj.id, ": ", obj.name, " of type ", obj.type
                meshdata = []

                # retrieving name
                n = obj.name
                if not n:
                    n = "Unnamed"

                # build shape
                shape = None
                if useShapes:
                    shape = getShape(obj)

                # skip types
                if obj.type in SKIP:
                    pass

                # walls
                elif obj.type == "IfcWallStandardCase":
                    makeWall(ifc.Entities[obj.id], shape)

                # windows
                elif obj.type in ["IfcWindow", "IfcDoor"]:
                    makeWindow(ifc.Entities[obj.id], shape)

                # structs
                elif obj.type in ["IfcBeam", "IfcColumn", "IfcSlab"]:
                    makeStructure(ifc.Entities[obj.id], shape)

                # furniture
                elif obj.type == "IfcFurnishingElement":
                    nobj = FreeCAD.ActiveDocument.addObject(
                        "Part::Feature", "Furniture")
                    nobj.Shape = shape

                elif shape:
                    # treat as dumb parts
                    nobj = FreeCAD.ActiveDocument.addObject("Part::Feature", n)
                    nobj.Shape = shape

                else:
                    # treat as meshes
                    me, pl = getMesh(obj)
                    nobj = FreeCAD.ActiveDocument.addObject("Mesh::Feature", n)
                    nobj.Mesh = me
                    nobj.Placement = pl

                if not IfcImport.Next():
                    break

        IfcImport.CleanUp()

    else:
        # use only the internal python parser

        # getting walls
        for w in ifc.getEnt("IfcWallStandardCase"):
            makeWall(w)

        # getting windows and doors
        for w in (ifc.getEnt("IfcWindow") + ifc.getEnt("IfcDoor")):
            makeWindow(w)

        # getting structs
        for w in (ifc.getEnt("IfcSlab") + ifc.getEnt("IfcBeam") +
                  ifc.getEnt("IfcColumn")):
            makeStructure(w)

    order(ifc)
    FreeCAD.ActiveDocument.recompute()
    t3 = time.time()
    if DEBUG: print "done processing", ifc, "in %s s" % ((t3 - t1))

    return None
예제 #11
0
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
예제 #12
0
def getShape(obj,objid):
    "gets a shape from an IfcOpenShell object"
    #print "retrieving shape from obj ",objid
    import Part
    sh=Part.Shape()
    brep_data = None
    if IFCOPENSHELL5:
        try:
            if SEPARATE_OPENINGS and hasattr(IfcImport,"DISABLE_OPENING_SUBTRACTIONS"):
                if SEPARATE_PLACEMENTS and hasattr(IfcImport,"DISABLE_OBJECT_PLACEMENT"):
                    brep_data = IfcImport.create_shape(obj,IfcImport.DISABLE_OPENING_SUBTRACTIONS | IfcImport.DISABLE_OBJECT_PLACEMENT)
                else:
                    brep_data = IfcImport.create_shape(obj,IfcImport.DISABLE_OPENING_SUBTRACTIONS)
            else:
                if SEPARATE_PLACEMENTS and hasattr(IfcImport,"DISABLE_OBJECT_PLACEMENT"):
                    brep_data = IfcImport.create_shape(obj,IfcImport.DISABLE_OBJECT_PLACEMENT)
                else:
                    brep_data = IfcImport.create_shape(obj)
        except:
            print "Unable to retrieve shape data"
    else:
        brep_data = obj.mesh.brep_data
    if brep_data:
        try:
            if MAKETEMPFILES:
                import tempfile
                tf = tempfile.mkstemp(suffix=".brp")[1]
                of = pyopen(tf,"wb")
                of.write(brep_data)
                of.close()
                sh = Part.read(tf)
                os.remove(tf)
            else:
                sh.importBrepFromString(brep_data)
        except:
            print "    error: malformed shape"
            return None
        else:
            if IFCOPENSHELL5 and SEPARATE_PLACEMENTS:
                p = getPlacement(getAttr(obj,"ObjectPlacement"))
                if p:
                    sh.Placement = p
    if not sh.Solids:
        # try to extract a solid shape
        if sh.Faces:
            try:
                if DEBUG: print "    malformed solid. Attempting to fix..."
                shell = Part.makeShell(sh.Faces)
                if shell:
                    solid = Part.makeSolid(shell)
                    if solid:
                        sh = solid
            except:
                if DEBUG: print "    failed to retrieve solid from object ",objid
        else:
            if DEBUG: print "    object ", objid, " doesn't contain any geometry"
    if not IFCOPENSHELL5:
        m = obj.matrix
        mat = FreeCAD.Matrix(m[0], m[3], m[6], m[9],
                             m[1], m[4], m[7], m[10],
                             m[2], m[5], m[8], m[11],
                             0, 0, 0, 1)
        sh.Placement = FreeCAD.Placement(mat)
    # if DEBUG: print "getting Shape from ",obj 
    #print "getting shape: ",sh,sh.Solids,sh.Volume,sh.isValid(),sh.isNull()
    #for v in sh.Vertexes: print v.Point
    return sh
예제 #13
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