Ejemplo n.º 1
0
def export(exportList,filename):
    "called when freecad exports a file"
    try:
        import IfcImport
    except:
        FreeCAD.Console.PrintError(translate("Arch","Error: IfcOpenShell is not installed\n"))
        print """importIFC: ifcOpenShell is not installed. IFC export is unavailable.
                 Note: IFC export currently requires an experimental version of IfcOpenShell
                 available from https://github.com/aothms/IfcOpenShell"""
        return
    else:
        if not hasattr(IfcImport,"IfcFile"):
            FreeCAD.Console.PrintError(translate("Arch","Error: your IfcOpenShell version is too old\n"))
            print """importIFC: The version of ifcOpenShell installed on this system doesn't
                     have IFC export capabilities. IFC export currently requires an experimental 
                     version of IfcOpenShell available from https://github.com/aothms/IfcOpenShell"""
            return
        import ifcWriter
    import Arch,Draft

    # creating base IFC project
    getConfig()
    ifcWriter.PRECISION = Draft.precision()
    p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
    scaling = p.GetFloat("IfcScalingFactor",1.0)
    exporttxt = p.GetBool("IfcExportList",False)
    forcebrep = p.GetBool("ifcExportAsBrep",False)
    application = "FreeCAD"
    ver = FreeCAD.Version()
    version = ver[0]+"."+ver[1]+" build"+ver[2]
    owner = FreeCAD.ActiveDocument.CreatedBy
    company = FreeCAD.ActiveDocument.Company
    project = FreeCAD.ActiveDocument.Name
    ifc = ifcWriter.IfcDocument(filename,project,owner,company,application,version)
    txt = []

    # get all children and reorder list to get buildings and floors processed first
    objectslist = Draft.getGroupContents(exportList,walls=True,addgroups=True)
    objectslist = Arch.pruneIncluded(objectslist)

    buildings = []
    floors = []
    others = []
    for obj in objectslist:
        otype = Draft.getType(obj)
        if otype == "Building":
            buildings.append(obj)
        elif otype == "Floor":
            floors.append(obj)
        else:
            others.append(obj)
    objectslist = buildings + floors + others
    if DEBUG: print "adding ", len(objectslist), " objects"
    
    global unprocessed
    unprocessed = []

    # process objects
    for obj in objectslist:

        otype = Draft.getType(obj)
        name = str(obj.Label)
        parent = Arch.getHost(obj)
        gdata = None
        fdata = None
        placement = None
        color = None
        representation = None
        descr = None
        extra = None
            
        # setting the IFC type
        if hasattr(obj,"Role"):
            ifctype = obj.Role.replace(" ","")
        else:
            ifctype = otype
        if ifctype == "Foundation":
            ifctype = "Footing"
        elif ifctype == "Rebar":
            ifctype = "ReinforcingBar"

        if DEBUG: print "adding " + obj.Label + " as Ifc" + ifctype
                 
        # writing IFC data 
        if obj.isDerivedFrom("App::DocumentObjectGroup"):
            
            # getting parent building
            if parent:
                parent = ifc.findByName("IfcBuilding",str(parent.Label))

            if otype == "Building":
                ifc.addBuilding( name=name )
            elif otype == "Floor":
                ifc.addStorey( building=parent, name=name )
            else:
                print "   Skipping (not implemented yet)"

        elif obj.isDerivedFrom("Part::Feature"):

            # get color
            if FreeCAD.GuiUp:
                color = obj.ViewObject.ShapeColor[:3]

            # get parent floor
            if parent:
                parent = ifc.findByName("IfcBuildingStorey",str(parent.Label))

            # get representation
            if not forcebrep:
                gdata = Arch.getIfcExtrusionData(obj,scaling)
                #if DEBUG: print "   extrusion data for ",obj.Label," : ",gdata
            if not gdata:
                fdata = Arch.getIfcBrepFacesData(obj,scaling)
                #if DEBUG: print "   brep data for ",obj.Label," : ",fdata
                if not fdata:
                    if obj.isDerivedFrom("Part::Feature"):
                        print "IFC export: error retrieving the shape of object ", obj.Name
                        continue
                    else:
                        if DEBUG: print "   No geometry"
                else:
                    if DEBUG: print "   Brep"
            else:
                if DEBUG: print "   Extrusion"
            if gdata:
                placement = ifc.addPlacement(origin=gdata[3][0],xaxis=gdata[3][1],zaxis=gdata[3][2])
                if gdata[0] == "polyline":
                    representation = ifc.addExtrudedPolyline(gdata[1], gdata[2], color=color)
                elif gdata[0] == "circle":
                    representation = ifc.addExtrudedCircle(gdata[1][0], gdata[1][1], gdata[2], color=color)
                elif gdata[0] == "ellipse":
                    representation = ifc.addExtrudedEllipse(gdata[1][0], gdata[1][1], gdata[1][2], gdata[2], color=color)
                else:
                    print "debug: unknow extrusion type"
            elif fdata:
                if JOINSOLIDS:
                    representation = ifc.join([ifc.addFacetedBrep(f, color=color) for f in fdata])
                else:
                    representation = [ifc.addFacetedBrep(f, color=color) for f in fdata]

            # create ifc object
            ifctype = "Ifc" + ifctype
            if hasattr(obj,"Description"):
                descr = obj.Description
            if otype == "Wall":
                if gdata:
                    if gdata[0] == "polyline":
                        ifctype = "IfcWallStandardCase"
            elif otype == "Structure":
                if ifctype in ["IfcSlab","IfcFooting"]:
                    extra = ["NOTDEFINED"]
            elif otype == "Window":
                extra = [obj.Width.Value*scaling, obj.Height.Value*scaling]
            if not ifctype in supportedIfcTypes:
                if DEBUG: print "   Type ",ifctype," is not supported by the current version of IfcOpenShell. Exporting as IfcBuildingElementProxy instead"
                ifctype = "IfcBuildingElementProxy"
                extra = ["ELEMENT"]
            p = ifc.addProduct( ifctype, representation, storey=parent, placement=placement, name=name, description=descr, extra=extra )
            if p:
                # writing text log
                spacer = ""
                for i in range(36-len(obj.Label)):
                    spacer += " "
                txt.append(obj.Label + spacer + ifctype)
            else:
                unprocessed.append(obj)
        else:
            if DEBUG: print "IFC export: object type ", otype, " is not supported yet."

            
    ifc.write()

    if exporttxt:
        import time, os
        txtstring = "List of objects exported by FreeCAD in file\n"
        txtstring += filename + "\n"
        txtstring += "On " + time.ctime() + "\n"
        txtstring += "\n"
        txtstring += str(len(txt)) + " objects exported:\n"
        txtstring += "\n"
        txtstring += "Nr      Name                          Type\n"
        txtstring += "\n"
        for i in range(len(txt)):
            idx = str(i+1)
            sp = ""
            for j in range(8-len(idx)):
                sp += " "
            txtstring += idx + sp + txt[i] + "\n"
        txtfile = os.path.splitext(filename)[0]+".txt"
        f = pyopen(txtfile,"wb")
        f.write(txtstring)
        f.close()

    FreeCAD.ActiveDocument.recompute()
    
    if unprocessed:
        print "Some objects were not exported. See importIFC.unprocessed"
Ejemplo n.º 2
0
def export(exportList, filename):
    "called when freecad exports a file"
    try:
        import IfcImport
    except:
        print """importIFC: ifcOpenShell is not installed. IFC export is unavailable.
                 Note: IFC export currently requires an experimental version of IfcOpenShell
                 available from https://github.com/aothms/IfcOpenShell"""
        return
    else:
        if not hasattr(IfcImport, "IfcFile"):
            print """importIFC: The version of ifcOpenShell installed on this system doesn't
                     have IFC export capabilities. IFC export currently requires an experimental 
                     version of IfcOpenShell available from https://github.com/aothms/IfcOpenShell"""
            return
        import ifcWriter

    # creating base IFC project
    import Arch, Draft
    getConfig()
    ifcWriter.PRECISION = Draft.precision()
    p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
    scaling = p.GetFloat("IfcScalingFactor", 1.0)
    application = "FreeCAD"
    ver = FreeCAD.Version()
    version = ver[0] + "." + ver[1] + " build" + ver[2]
    owner = FreeCAD.ActiveDocument.CreatedBy
    company = FreeCAD.ActiveDocument.Company
    project = FreeCAD.ActiveDocument.Name
    ifc = ifcWriter.IfcDocument(filename, project, owner, company, application,
                                version)

    # get all children and reorder list to get buildings and floors processed first
    objectslist = Draft.getGroupContents(exportList,
                                         walls=True,
                                         addgroups=True)
    objectslist = Arch.pruneIncluded(objectslist)
    buildings = []
    floors = []
    others = []
    for obj in objectslist:
        otype = Draft.getType(obj)
        if otype == "Building":
            buildings.append(obj)
        elif otype == "Floor":
            floors.append(obj)
        else:
            others.append(obj)
    objectslist = buildings + floors + others
    if DEBUG: print "adding ", len(objectslist), " objects"

    # process objects
    for obj in objectslist:
        if DEBUG: print "adding ", obj.Label
        otype = Draft.getType(obj)
        name = str(obj.Label)
        parent = Arch.getHost(obj)
        gdata = Arch.getExtrusionData(obj, scaling)
        if not gdata:
            fdata = Arch.getBrepFacesData(obj, scaling)
            if not fdata:
                if obj.isDerivedFrom("Part::Feature"):
                    print "IFC export: error retrieving the shape of object ", obj.Name
                    continue

        if otype == "Building":
            ifc.addBuilding(name=name)

        elif otype == "Floor":
            if parent:
                parent = ifc.findByName("IfcBuilding", str(parent.Label))
            ifc.addStorey(building=parent, name=name)

        elif otype == "Wall":
            if parent:
                parent = ifc.findByName("IfcBuildingStorey", str(parent.Label))
            if gdata:
                ifc.addWall(ifc.addExtrudedPolyline(gdata[0], gdata[1]),
                            storey=parent,
                            name=name)
            elif fdata:
                ifc.addWall([ifc.addFacetedBrep(f) for f in fdata],
                            storey=parent,
                            name=name)

        elif otype == "Structure":
            if parent:
                parent = ifc.findByName("IfcBuildingStorey", str(parent.Label))
            role = "IfcBeam"
            if hasattr(obj, "Role"):
                if obj.Role == "Column":
                    role = "IfcColumn"
                elif obj.Role == "Slab":
                    role = "IfcSlab"
                elif obj.Role == "Foundation":
                    role = "IfcFooting"
            if gdata:
                if FreeCAD.Vector(gdata[1]).getAngle(FreeCAD.Vector(0, 0,
                                                                    1)) < .01:
                    # Workaround for non-Z extrusions, apparently not supported by ifc++ TODO: fix this
                    ifc.addStructure(role,
                                     ifc.addExtrudedPolyline(
                                         gdata[0], gdata[1]),
                                     storey=parent,
                                     name=name)
                else:
                    fdata = Arch.getBrepFacesData(obj, scaling)
                    ifc.addStructure(role,
                                     [ifc.addFacetedBrep(f) for f in fdata],
                                     storey=parent,
                                     name=name)
            elif fdata:
                ifc.addStructure(role, [ifc.addFacetedBrep(f) for f in fdata],
                                 storey=parent,
                                 name=name)

        elif otype == "Window":
            if parent:
                p = ifc.findByName("IfcWallStandardCase", str(parent.Label))
                if not p:
                    p = ifc.findByName("IfcColumn", str(parent.Label))
                    if not p:
                        p = ifc.findByName("IfcBeam", str(parent.Label))
                        if not p:
                            p = ifc.findByName("IfcSlab", str(parent.Label))
                parent = p
            role = "IfcWindow"
            if hasattr(obj, "Role"):
                if obj.Role == "Door":
                    role = "IfcDoor"
            if gdata:
                ifc.addWindow(role,
                              obj.Width * scaling,
                              obj.Height * scaling,
                              ifc.addExtrudedPolyline(gdata[0], gdata[1]),
                              host=parent,
                              name=name)
            elif fdata:
                ifc.addWindow(role,
                              obj.Width * scaling,
                              obj.Height * scaling,
                              [ifc.addFacetedBrep(f) for f in fdata],
                              host=parent,
                              name=name)

        else:
            print "IFC export: object type ", otype, " is not supported yet."

    ifc.write()