Arch: Better sticking to standards in IFC import/export
This commit is contained in:
parent
8609337d6f
commit
cd7c1f2307
|
@ -602,7 +602,7 @@ def addFixture(fixture,baseobject):
|
|||
else:
|
||||
FreeCAD.Console.PrintMessage(translate("Arch","This object has no support for fixtures"))
|
||||
|
||||
def getTuples(data,scale=1,placement=None,normal=None):
|
||||
def getTuples(data,scale=1,placement=None,normal=None,close=True):
|
||||
"""getTuples(data,[scale,placement,normal]): returns a tuple or a list of tuples from a vector
|
||||
or from the vertices of a shape. Scale can indicate a scale factor"""
|
||||
import Part
|
||||
|
@ -630,6 +630,7 @@ def getTuples(data,scale=1,placement=None,normal=None):
|
|||
if placement:
|
||||
pt = placement.multVec(pt)
|
||||
t.append((pt.x*scale,pt.y*scale,pt.z*scale))
|
||||
if close:
|
||||
t.append(t[0]) # for IFC verts lists must be closed
|
||||
else:
|
||||
print "Arch.getTuples(): Wrong profile data"
|
||||
|
@ -669,10 +670,10 @@ def getBrepFacesData(obj,scale=1):
|
|||
s = []
|
||||
for face in obj.Shape.Faces:
|
||||
f = []
|
||||
f.append(getTuples(face.OuterWire,scale,normal=face.normalAt(0,0)))
|
||||
f.append(getTuples(face.OuterWire,scale,normal=face.normalAt(0,0),close=False))
|
||||
for wire in face.Wires:
|
||||
if wire.hashCode() != face.OuterWire.hashCode():
|
||||
f.append(getTuples(wire,scale,normal=DraftVecUtils.neg(face.normalAt(0,0))))
|
||||
f.append(getTuples(wire,scale,normal=DraftVecUtils.neg(face.normalAt(0,0)),close=False))
|
||||
s.append(f)
|
||||
sols.append(s)
|
||||
return sols
|
||||
|
|
|
@ -240,7 +240,7 @@ def makeWall(ifcdoc,storey,owner,context,shape,placement=None,name="Default wall
|
|||
in the given ifc document"""
|
||||
if not placement:
|
||||
placement = makePlacement(ifcdoc)
|
||||
rep = create(ifcdoc,"IfcShapeRepresentation",[context,'Body','SweptSolid',[shape]])
|
||||
rep = create(ifcdoc,"IfcShapeRepresentation",[context,'Body','SolidModel',[shape]])
|
||||
prd = create(ifcdoc,"IfcProductDefinitionShape",[None,None,[rep]])
|
||||
wal = create(ifcdoc,"IfcWallStandardCase",[uid(),owner,name,description,
|
||||
None,placement,prd,None])
|
||||
|
@ -375,6 +375,9 @@ class IfcDocument(object):
|
|||
elif "FILE_NAME" in l:
|
||||
# bug 4: incomplete file name entry
|
||||
l = l.replace("FILE_NAME('','',(''),('',''),'IfcOpenShell','IfcOpenShell','');","FILE_NAME('"+path+"','"+now(string=True)+"',('"+self.Owner+"'),('',''),'IfcOpenShell','IfcOpenShell','');")
|
||||
elif "IFCSIUNIT" in l:
|
||||
# bug 5: no way to insert * character
|
||||
l = l.replace("IFCSIUNIT(#13,","IFCSIUNIT(*,")
|
||||
lines.append(l)
|
||||
f.close()
|
||||
f = open(path,"wb")
|
||||
|
@ -441,7 +444,11 @@ class IfcDocument(object):
|
|||
placement = self.addPlacement()
|
||||
if not isinstance(shapes,list):
|
||||
shapes = [shapes]
|
||||
reps = [create(self._fileobject,"IfcShapeRepresentation",[self._repcontext,'Body','SweptSolid',[shape]]) for shape in shapes]
|
||||
if standard:
|
||||
solidType = "SweptSolid"
|
||||
else:
|
||||
solidType = "Brep"
|
||||
reps = [create(self._fileobject,"IfcShapeRepresentation",[self._repcontext,'Body',solidType,[shape]]) for shape in shapes]
|
||||
prd = create(self._fileobject,"IfcProductDefinitionShape",[None,None,reps])
|
||||
if standard:
|
||||
wal = create(self._fileobject,"IfcWallStandardCase",[uid(),self._owner,name,description,None,placement,prd,None])
|
||||
|
@ -456,14 +463,18 @@ class IfcDocument(object):
|
|||
self._relate(storey,wal)
|
||||
return wal
|
||||
|
||||
def addStructure(self,ifctype,shapes,storey=None,placement=None,name="Default Structure",description=None):
|
||||
def addStructure(self,ifctype,shapes,storey=None,placement=None,name="Default Structure",description=None,standard=False):
|
||||
"""addStructure(ifctype,shapes,[storey,placement,name,description]): creates a structure
|
||||
from the given representation shape(s). Ifctype is the type of structural object (IfcBeam, IfcColumn, etc)"""
|
||||
if not placement:
|
||||
placement = self.addPlacement()
|
||||
if not isinstance(shapes,list):
|
||||
shapes = [shapes]
|
||||
reps = [create(self._fileobject,"IfcShapeRepresentation",[self._repcontext,'Body','SweptSolid',[shape]]) for shape in shapes]
|
||||
if standard:
|
||||
solidType = "SweptSolid"
|
||||
else:
|
||||
solidType = "Brep"
|
||||
reps = [create(self._fileobject,"IfcShapeRepresentation",[self._repcontext,'Body',solidType,[shape]]) for shape in shapes]
|
||||
prd = create(self._fileobject,"IfcProductDefinitionShape",[None,None,reps])
|
||||
if ifctype in ["IfcSlab","IfcFooting"]:
|
||||
stt = create(self._fileobject,ifctype,[uid(),self._owner,name,description,None,placement,prd,None,"NOTDEFINED"])
|
||||
|
@ -485,7 +496,7 @@ class IfcDocument(object):
|
|||
placement = self.addPlacement()
|
||||
if not isinstance(shapes,list):
|
||||
shapes = [shapes]
|
||||
reps = [create(self._fileobject,"IfcShapeRepresentation",[self._repcontext,'Body','SweptSolid',[shape]]) for shape in shapes]
|
||||
reps = [create(self._fileobject,"IfcShapeRepresentation",[self._repcontext,'Body','SolidModel',[shape]]) for shape in shapes]
|
||||
prd = create(self._fileobject,"IfcProductDefinitionShape",[None,None,reps])
|
||||
win = create(self._fileobject,ifctype,[uid(),self._owner,name,description,None,placement,prd,None,float(height),float(width)])
|
||||
self.BuildingProducts.append(win)
|
||||
|
|
|
@ -30,8 +30,10 @@ __url__ = "http://www.freecadweb.org"
|
|||
|
||||
# config
|
||||
subtractiveTypes = ["IfcOpeningElement"] # elements that must be subtracted from their parents
|
||||
SCHEMA = "http://www.steptools.com/support/stdev_docs/express/ifc2x3/ifc2x3_tc1.exp"
|
||||
SCHEMA = "http://www.steptools.com/support/stdev_docs/express/ifc2x3/ifc2x3_tc1.exp" # only for internal prser
|
||||
MAKETEMPFILES = False # if True, shapes are passed from ifcopenshell to freecad through temp files
|
||||
DEBUG = True # this is only for the python console, this value is overridden when importing through the GUI
|
||||
SKIP = ["IfcBuildingElementProxy","IfcFlowTerminal","IfcFurnishingElement"] # default. overwritten by the GUI options
|
||||
# end config
|
||||
|
||||
if open.__module__ == '__builtin__':
|
||||
|
@ -60,11 +62,9 @@ def insert(filename,docname,skip=None):
|
|||
|
||||
def getConfig():
|
||||
"Gets Arch IFC import preferences"
|
||||
global CREATE_IFC_GROUPS, ASMESH, DEBUG, SKIP, PREFIX_NUMBERS, FORCE_PYTHON_PARSER, SEPARATE_OPENINGS, SEPARATE_PLACEMENTS
|
||||
global CREATE_IFC_GROUPS, ASMESH, PREFIX_NUMBERS, FORCE_PYTHON_PARSER, SEPARATE_OPENINGS, SEPARATE_PLACEMENTS
|
||||
CREATE_IFC_GROUPS = False
|
||||
IMPORT_IFC_FURNITURE = False
|
||||
DEBUG = False
|
||||
SKIP = ["IfcBuildingElementProxy","IfcFlowTerminal","IfcFurnishingElement"]
|
||||
ASMESH = ["IfcFurnishingElement"]
|
||||
PREFIX_NUMBERS = False
|
||||
FORCE_PYTHON_PARSER = False
|
||||
|
@ -318,12 +318,12 @@ def read(filename,skip=None):
|
|||
else:
|
||||
# creating parent if needed
|
||||
if IFCOPENSHELL5:
|
||||
parent_ifcobj = ifc.by_id(parent_id)
|
||||
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:
|
||||
parent_ifcobj = IfcImport.GetObject(parent_id)
|
||||
obj = IfcImport.GetObject(parent_id)
|
||||
parentid = obj.id
|
||||
parentname = obj.name
|
||||
parenttype = obj.type
|
||||
|
@ -343,6 +343,8 @@ def read(filename,skip=None):
|
|||
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
|
||||
|
@ -677,7 +679,7 @@ def getShape(obj,objid):
|
|||
else:
|
||||
sh.importBrepFromString(brep_data)
|
||||
except:
|
||||
print "Error: malformed shape"
|
||||
print " error: malformed shape"
|
||||
return None
|
||||
else:
|
||||
if IFCOPENSHELL5 and SEPARATE_PLACEMENTS:
|
||||
|
@ -688,7 +690,7 @@ def getShape(obj,objid):
|
|||
# try to extract a solid shape
|
||||
if sh.Faces:
|
||||
try:
|
||||
if DEBUG: print "Malformed solid. Attempting to fix..."
|
||||
if DEBUG: print " malformed solid. Attempting to fix..."
|
||||
shell = Part.makeShell(sh.Faces)
|
||||
if shell:
|
||||
solid = Part.makeSolid(shell)
|
||||
|
@ -1026,7 +1028,7 @@ def export(exportList,filename):
|
|||
#ifc.addStructure( role, ifc.addExtrudedPolyline(gdata[0],gdata[1]), storey=parent, name=name )
|
||||
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 )
|
||||
ifc.addStructure( role, ifc.addExtrudedPolyline(gdata[0],gdata[1]), storey=parent, name=name, standard=True )
|
||||
else:
|
||||
fdata = Arch.getBrepFacesData(obj,scaling)
|
||||
ifc.addStructure( role, [ifc.addFacetedBrep(f) for f in fdata], storey=parent, name=name )
|
||||
|
@ -1036,6 +1038,8 @@ def export(exportList,filename):
|
|||
elif otype == "Window":
|
||||
if parent:
|
||||
p = ifc.findByName("IfcWallStandardCase",str(parent.Label))
|
||||
if not p:
|
||||
p = ifc.findByName("IfcWall",str(parent.Label))
|
||||
if not p:
|
||||
p = ifc.findByName("IfcColumn",str(parent.Label))
|
||||
if not p:
|
||||
|
|
Loading…
Reference in New Issue
Block a user