Arch: Added support for IfcOpenShell serializer

This commit is contained in:
Yorik van Havre 2016-06-04 17:43:41 -03:00
parent dad057cac5
commit 27b4836d80
3 changed files with 132 additions and 71 deletions

View File

@ -383,8 +383,8 @@ class Component:
if obj.Base.isDerivedFrom("Part::Extrusion"):
if obj.Base.Base:
base = obj.Base.Base.Shape.copy()
if noplacement:
base.Placement = FreeCAD.Placement()
#if noplacement:
# base.Placement = FreeCAD.Placement()
return [base]
elif obj.Base.isDerivedFrom("Part::Feature"):
if obj.Base.Shape:

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>456</width>
<height>579</height>
<height>608</height>
</rect>
</property>
<property name="windowTitle">
@ -430,6 +430,26 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_16">
<item>
<widget class="Gui::PrefCheckBox" name="checkBox_10">
<property name="toolTip">
<string>Warning, experimental feature!</string>
</property>
<property name="text">
<string>Use IfcOpenShell serializer if available</string>
</property>
<property name="prefEntry" stdset="0">
<cstring>ifcSerialize</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>Mod/Arch</cstring>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>

View File

@ -124,7 +124,7 @@ def getPreferences():
global DEBUG, PREFIX_NUMBERS, SKIP, SEPARATE_OPENINGS
global ROOT_ELEMENT, GET_EXTRUSIONS, MERGE_MATERIALS
global MERGE_MODE_ARCH, MERGE_MODE_STRUCT, CREATE_CLONES
global FORCE_BREP, IMPORT_PROPERTIES, STORE_UID
global FORCE_BREP, IMPORT_PROPERTIES, STORE_UID, SERIALIZE
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
if FreeCAD.GuiUp and p.GetBool("ifcShowDialog",False):
import FreeCADGui
@ -147,6 +147,7 @@ def getPreferences():
FORCE_BREP = p.GetBool("ifcExportAsBrep",False)
IMPORT_PROPERTIES = p.GetBool("ifcImportProperties",False)
STORE_UID = p.GetBool("ifcStoreUid",True)
SERIALIZE = p.GetBool("ifcSerialize",False)
def explore(filename=None):
@ -529,7 +530,17 @@ def insert(filename,docname,skip=[],only=[],root=None):
if ex:
print "extrusion ",
baseface = FreeCAD.ActiveDocument.addObject("Part::Feature",name+"_footprint")
baseface.Shape = ex[0]
# bug in ifcopenshell? Some faces of a shell may have non-null placement
# workaround to remove the bad placement: exporting/reimporting as step
if not ex[0].Placement.isNull():
import tempfile
tf = tempfile.mkstemp(suffix=".stp")[1]
ex[0].exportStep(tf)
f = Part.read(tf)
os.remove(tf)
else:
f = ex[0]
baseface.Shape = f
baseobj = FreeCAD.ActiveDocument.addObject("Part::Extrusion",name+"_body")
baseobj.Base = baseface
baseobj.Dir = ex[1]
@ -1242,6 +1253,16 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
p.scale(0.001) # to meters
r = obj.Proxy.getPlacement(obj)
r.Base = r.Base.multiply(0.001) # to meters
d = DraftGeomUtils.getNormal(p.Wires[0])
if r.isNull() and ( (p.CenterOfMass.z > 0.001) or ( (d.getAngle(FreeCAD.Vector(0,0,1)) > 0.001) and (d.getAngle(FreeCAD.Vector(0,0,1)) < 3.14159) ) ):
# the object placement in null, but the profile is not in the XY plane.
npla = FreeCAD.Placement()
npla.Base = p.CenterOfMass
nrot = FreeCAD.Rotation(FreeCAD.Vector(0,0,1),d)
npla.Rotation = nrot
r = npla
p.Placement = npla.inverse() # move the profile to origin
extrusionv = nrot.inverted().multVec(extrusionv) # move the extrusion vector to Z axis
if len(p.Edges) == 1:
@ -1318,7 +1339,7 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
pol = ifcfile.createIfcCompositeCurve(segments,False)
profile = ifcfile.createIfcArbitraryClosedProfileDef("AREA",None,pol)
if profile:
if profile and not(DraftVecUtils.isNull(extrusionv)):
xvc = ifcfile.createIfcDirection(tuple(r.Rotation.multVec(FreeCAD.Vector(1,0,0))))
zvc = ifcfile.createIfcDirection(tuple(r.Rotation.multVec(FreeCAD.Vector(0,0,1))))
ovc = ifcfile.createIfcCartesianPoint(tuple(r.Base))
@ -1355,6 +1376,23 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
else:
dataset = fcshape.Shells
if DEBUG: print "Warning! object contains no solids"
# new ifcopenshell serializer
from ifcopenshell import geom
if hasattr(geom,"serialise") and obj.isDerivedFrom("Part::Feature") and SERIALIZE:
p = geom.serialise(obj.Shape.exportBrepToString())
productdef = ifcfile.add(p)
for rep in productdef.Representations:
rep.ContextOfItems = context
xvc = ifcfile.createIfcDirection((1.0,0.0,0.0))
zvc = ifcfile.createIfcDirection((0.0,0.0,1.0))
ovc = ifcfile.createIfcCartesianPoint((0.0,0.0,0.0))
gpl = ifcfile.createIfcAxis2Placement3D(ovc,zvc,xvc)
placement = ifcfile.createIfcLocalPlacement(None,gpl)
shapetype = "advancedbrep"
shapes = None
else:
# old method
for fcsolid in dataset:
fcsolid.scale(0.001) # to meters
faces = []
@ -1363,9 +1401,12 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
for fcface in fcsolid.Faces:
for e in fcface.Edges:
if DraftGeomUtils.geomType(e) != "Line":
try:
if e.curvatureAt(e.FirstParameter+(e.LastParameter-e.FirstParameter)/2) > 0.0001:
curves = True
break
except Part.OCCError:
pass
if curves:
joinfacets = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetBool("ifcJoinCoplanarFacets",False)
usedae = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch").GetBool("ifcUseDaeOptions",False)