Arch: IFC exporter now exports 2D geometry as IfcAnnotations
This commit is contained in:
parent
8eedc79f35
commit
0ad956c45b
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>456</width>
|
||||
<height>637</height>
|
||||
<height>666</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -470,6 +470,26 @@
|
|||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_18">
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="checkBox_12">
|
||||
<property name="text">
|
||||
<string>Export 2D objects as IfcAnnotations</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>ifcExport2D</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Arch</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -126,7 +126,7 @@ def getPreferences():
|
|||
global ROOT_ELEMENT, GET_EXTRUSIONS, MERGE_MATERIALS
|
||||
global MERGE_MODE_ARCH, MERGE_MODE_STRUCT, CREATE_CLONES
|
||||
global FORCE_BREP, IMPORT_PROPERTIES, STORE_UID, SERIALIZE
|
||||
global SPLIT_LAYERS
|
||||
global SPLIT_LAYERS, EXPORT_2D
|
||||
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
|
||||
if FreeCAD.GuiUp and p.GetBool("ifcShowDialog",False):
|
||||
import FreeCADGui
|
||||
|
@ -151,6 +151,7 @@ def getPreferences():
|
|||
STORE_UID = p.GetBool("ifcStoreUid",True)
|
||||
SERIALIZE = p.GetBool("ifcSerialize",False)
|
||||
SPLIT_LAYERS = p.GetBool("ifcSplitLayers",False)
|
||||
EXPORT_2D = p.GetBool("ifcExport2D",True)
|
||||
|
||||
|
||||
def explore(filename=None):
|
||||
|
@ -963,6 +964,16 @@ def export(exportList,filename):
|
|||
context = ifcfile.by_type("IfcGeometricRepresentationContext")[0]
|
||||
project = ifcfile.by_type("IfcProject")[0]
|
||||
objectslist = Draft.getGroupContents(exportList,walls=True,addgroups=True)
|
||||
annotations = []
|
||||
for obj in objectslist:
|
||||
if obj.isDerivedFrom("Part::Part2DObject"):
|
||||
annotations.append(obj)
|
||||
elif obj.isDerivedFrom("App::Annotation"):
|
||||
annotations.append(obj)
|
||||
elif obj.isDerivedFrom("Part::Feature"):
|
||||
if obj.Shape:
|
||||
if not obj.Shape.Faces:
|
||||
annotations.append(obj)
|
||||
objectslist = Arch.pruneIncluded(objectslist)
|
||||
products = {} # { Name: IfcEntity, ... }
|
||||
surfstyles = {} # { (r,g,b): IfcEntity, ... }
|
||||
|
@ -1300,7 +1311,37 @@ def export(exportList,filename):
|
|||
products[g[0]] = grp
|
||||
ass = ifcfile.createIfcRelAssignsToGroup(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'GroupLink','',children,None,grp)
|
||||
|
||||
|
||||
# 2D objects
|
||||
|
||||
if EXPORT_2D:
|
||||
if annotations and DEBUG: print "exporting 2D objects..."
|
||||
for anno in annotations:
|
||||
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)
|
||||
if anno.isDerivedFrom("Part::Feature"):
|
||||
reps = []
|
||||
sh = anno.Shape.copy()
|
||||
sh.scale(0.001) # to meters
|
||||
ehc = []
|
||||
for w in sh.Wires:
|
||||
reps.append(createCurve(ifcfile,w))
|
||||
for e in w.Edges:
|
||||
ehc.append(e.hashCode())
|
||||
for e in sh.Edges:
|
||||
if not e.hashCode in ehc:
|
||||
reps.append(createCurve(ifcfile,e))
|
||||
elif anno.isDerivedFrom("App::Annotation"):
|
||||
l = anno.Position
|
||||
pos = ifcfile.createIfcCartesianPoint((l.x,l.y,l.z))
|
||||
tpl = ifcfile.createIfcAxis2Placement3D(pos,None,None)
|
||||
txt = ifcfile.createIfcTextLiteral(";".join(anno.LabelText).encode("utf8"),tpl,"LEFT")
|
||||
reps = [txt]
|
||||
shp = ifcfile.createIfcShapeRepresentation(context,'Annotation','Annotation2D',reps)
|
||||
rep = ifcfile.createIfcProductDefinitionShape(None,None,[shp])
|
||||
ann = ifcfile.createIfcAnnotation(ifcopenshell.guid.compress(uuid.uuid1().hex),history,anno.Label.encode('utf8'),'',None,gpl,rep)
|
||||
|
||||
if DEBUG: print "writing ",filename,"..."
|
||||
|
||||
filename = decode(filename)
|
||||
|
@ -1314,6 +1355,60 @@ def export(exportList,filename):
|
|||
os.remove(templatefile)
|
||||
|
||||
|
||||
def createCurve(ifcfile,wire):
|
||||
"creates an IfcCompositeCurve from a shape"
|
||||
|
||||
segments = []
|
||||
pol = None
|
||||
last = None
|
||||
if wire.ShapeType == "edge":
|
||||
edges = [edge]
|
||||
else:
|
||||
edges = Part.__sortEdges__(wire.Edges)
|
||||
for e in edges:
|
||||
if isinstance(e.Curve,Part.Circle):
|
||||
follow = True
|
||||
if last:
|
||||
if not DraftVecUtils.equals(last,e.Vertexes[0].Point):
|
||||
follow = False
|
||||
last = e.Vertexes[0].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
p1 = math.degrees(-DraftVecUtils.angle(e.Vertexes[0].Point.sub(e.Curve.Center)))
|
||||
p2 = math.degrees(-DraftVecUtils.angle(e.Vertexes[-1].Point.sub(e.Curve.Center)))
|
||||
da = DraftVecUtils.angle(e.valueAt(e.FirstParameter+0.1).sub(e.Curve.Center),e.Vertexes[0].Point.sub(e.Curve.Center))
|
||||
if p1 < 0:
|
||||
p1 = 360 + p1
|
||||
if p2 < 0:
|
||||
p2 = 360 + p2
|
||||
if da > 0:
|
||||
follow = not(follow)
|
||||
xvc = ifcfile.createIfcDirection((1.0,0.0))
|
||||
ovc = ifcfile.createIfcCartesianPoint(tuple(e.Curve.Center)[:2])
|
||||
plc = ifcfile.createIfcAxis2Placement2D(ovc,xvc)
|
||||
cir = ifcfile.createIfcCircle(plc,e.Curve.Radius)
|
||||
curve = ifcfile.createIfcTrimmedCurve(cir,[ifcfile.createIfcParameterValue(p1)],[ifcfile.createIfcParameterValue(p2)],follow,"PARAMETER")
|
||||
else:
|
||||
verts = [vertex.Point for vertex in e.Vertexes]
|
||||
if last:
|
||||
if not DraftVecUtils.equals(last,verts[0]):
|
||||
verts.reverse()
|
||||
last = e.Vertexes[0].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
pts = [ifcfile.createIfcCartesianPoint(tuple(v)[:2]) for v in verts]
|
||||
curve = ifcfile.createIfcPolyline(pts)
|
||||
segment = ifcfile.createIfcCompositeCurveSegment("CONTINUOUS",True,curve)
|
||||
segments.append(segment)
|
||||
if segments:
|
||||
pol = ifcfile.createIfcCompositeCurve(segments,False)
|
||||
return pol
|
||||
|
||||
|
||||
def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tessellation=1):
|
||||
"""returns an IfcShapeRepresentation object or None"""
|
||||
|
||||
|
@ -1325,7 +1420,7 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
|
|||
tostore = False
|
||||
|
||||
# check for clones
|
||||
if not subtraction:
|
||||
if (not subtraction) and (not forcebrep):
|
||||
for k,v in clones.items():
|
||||
if (obj.Name == k ) or (obj.Name in v):
|
||||
if k in sharedobjects:
|
||||
|
@ -1399,51 +1494,7 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess
|
|||
|
||||
# extruded composite curve
|
||||
else:
|
||||
segments = []
|
||||
last = None
|
||||
edges = Part.__sortEdges__(p.Edges)
|
||||
for e in edges:
|
||||
if isinstance(e.Curve,Part.Circle):
|
||||
follow = True
|
||||
if last:
|
||||
if not DraftVecUtils.equals(last,e.Vertexes[0].Point):
|
||||
follow = False
|
||||
last = e.Vertexes[0].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
p1 = math.degrees(-DraftVecUtils.angle(e.Vertexes[0].Point.sub(e.Curve.Center)))
|
||||
p2 = math.degrees(-DraftVecUtils.angle(e.Vertexes[-1].Point.sub(e.Curve.Center)))
|
||||
da = DraftVecUtils.angle(e.valueAt(e.FirstParameter+0.1).sub(e.Curve.Center),e.Vertexes[0].Point.sub(e.Curve.Center))
|
||||
if p1 < 0:
|
||||
p1 = 360 + p1
|
||||
if p2 < 0:
|
||||
p2 = 360 + p2
|
||||
if da > 0:
|
||||
follow = not(follow)
|
||||
xvc = ifcfile.createIfcDirection((1.0,0.0))
|
||||
ovc = ifcfile.createIfcCartesianPoint(tuple(e.Curve.Center)[:2])
|
||||
plc = ifcfile.createIfcAxis2Placement2D(ovc,xvc)
|
||||
cir = ifcfile.createIfcCircle(plc,e.Curve.Radius)
|
||||
curve = ifcfile.createIfcTrimmedCurve(cir,[ifcfile.createIfcParameterValue(p1)],[ifcfile.createIfcParameterValue(p2)],follow,"PARAMETER")
|
||||
|
||||
else:
|
||||
verts = [vertex.Point for vertex in e.Vertexes]
|
||||
if last:
|
||||
if not DraftVecUtils.equals(last,verts[0]):
|
||||
verts.reverse()
|
||||
last = e.Vertexes[0].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
else:
|
||||
last = e.Vertexes[-1].Point
|
||||
pts = [ifcfile.createIfcCartesianPoint(tuple(v)[:2]) for v in verts]
|
||||
curve = ifcfile.createIfcPolyline(pts)
|
||||
segment = ifcfile.createIfcCompositeCurveSegment("CONTINUOUS",True,curve)
|
||||
segments.append(segment)
|
||||
|
||||
pol = ifcfile.createIfcCompositeCurve(segments,False)
|
||||
po = createCurve(ifcfile,p)
|
||||
profile = ifcfile.createIfcArbitraryClosedProfileDef("AREA",None,pol)
|
||||
|
||||
if profile and not(DraftVecUtils.isNull(extrusionv)):
|
||||
|
|
|
@ -1765,8 +1765,9 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct
|
|||
l = p.GetString("svgDashdotLine","0.09,0.05,0.02,0.05")
|
||||
elif linestyle == "Dotted":
|
||||
l = p.GetString("svgDottedLine","0.02,0.02")
|
||||
elif "," in linestyle:
|
||||
l = linestyle
|
||||
elif linestyle:
|
||||
if "," in linestyle:
|
||||
l = linestyle
|
||||
if l:
|
||||
l = l.split(",")
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue
Block a user