Arch: General optimization

+ More severe tests when constructing shapes
+ Allow to quickly export Arch views to DXF
This commit is contained in:
Yorik van Havre 2012-08-09 17:50:07 -03:00
parent 6cef178ae7
commit 70d4048b38
4 changed files with 105 additions and 70 deletions

View File

@ -191,7 +191,7 @@ class _ArchDrawingView:
obj.LineWidth = 0.35
obj.ShowCut = False
obj.Proxy = self
self.Type = "DrawingView"
self.Type = "ArchSectionView"
def execute(self, obj):
if obj.Source:
@ -207,16 +207,34 @@ class _ArchDrawingView:
def __setstate__(self,state):
return None
def getShape(self, obj):
def getDisplayModes(self,vobj):
modes=["Default"]
return modes
def setDisplayMode(self,mode):
return mode
def getFlatShape(self):
"returns a flat shape representation of the view"
if hasattr(self,"baseshape"):
import Drawing
[V0,V1,H0,H1] = Drawing.project(self.baseshape,direction)
[V0,V1,H0,H1] = Drawing.project(self.baseshape,self.direction)
return V0.Edges+V1.Edges
else:
print "No shape has been computed yet"
return None
def getDXF(self):
"returns a flat shape representation of the view"
if hasattr(self,"baseshape"):
import Drawing
[V0,V1,H0,H1] = Drawing.project(self.baseshape,self.direction)
DxfOutput = Drawing.projectToDXF(self.baseshape,self.direction)
return DxfOutput
else:
print "No shape has been computed yet"
return None
def updateSVG(self, obj,join=False):
"encapsulates a svg fragment into a transformation node"
import Part, DraftGeomUtils
@ -252,7 +270,7 @@ class _ArchDrawingView:
hshapes = []
sshapes = []
p = FreeCAD.Placement(obj.Source.Placement)
direction = p.Rotation.multVec(FreeCAD.Vector(0,0,1))
self.direction = p.Rotation.multVec(FreeCAD.Vector(0,0,1))
for o in objs:
if o.isDerivedFrom("Part::Feature"):
if o.Shape.isValid():
@ -265,23 +283,17 @@ class _ArchDrawingView:
for sh in shapes:
for sol in sh.Solids:
c = sol.cut(cutvolume)
nsh.append(c)
s = sol.section(cutface)
nsh.extend(c.Solids)
sshapes.append(s)
if obj.ShowCut:
c = sol.cut(invcutvolume)
hshapes.append(c)
shapes = nsh
if shapes:
self.shapes = shapes
self.baseshape = Part.makeCompound(shapes)
svgf = Drawing.projectToSVG(self.baseshape,direction)
#if shapes:
# base = shapes.pop().copy()
#for sh in shapes:
# try:
# base = base.fuse(sh)
# except:
# print "unable to fuse, passing..."
svgf = Drawing.projectToSVG(self.baseshape,self.direction)
if svgf:
svgf = svgf.replace('stroke-width="0.35"','stroke-width="' + str(linewidth) + 'px"')
svgf = svgf.replace('stroke-width="1"','stroke-width="' + str(linewidth) + 'px"')
@ -289,7 +301,7 @@ class _ArchDrawingView:
svg += svgf
if hshapes:
hshapes = Part.makeCompound(hshapes)
svgh = Drawing.projectToSVG(hshapes,direction)
svgh = Drawing.projectToSVG(hshapes,self.direction)
if svgh:
svgh = svgh.replace('stroke-width="0.35"','stroke-width="' + str(linewidth) + 'px"')
svgh = svgh.replace('stroke-width="1"','stroke-width="' + str(linewidth) + 'px"')
@ -306,7 +318,7 @@ class _ArchDrawingView:
if (w.ShapeType == "Wire") and w.isClosed():
faces.append(Part.Face(w))
sshapes = Part.makeCompound(faces)
svgs = Drawing.projectToSVG(sshapes,direction)
svgs = Drawing.projectToSVG(sshapes,self.direction)
if svgs:
svgs = svgs.replace('stroke-width="0.35"','stroke-width="' + str(linewidth*st) + 'px"')
svgs = svgs.replace('stroke-width="1"','stroke-width="' + str(linewidth*st) + 'px"')

View File

@ -222,7 +222,12 @@ class _Structure(ArchComponent.Component):
# finalizing
else:
if base:
if not base.isNull():
if base.isValid() and (not base.isNull()) and base.Solids:
if base.Volume < 0:
base.reverse()
if base.Volume < 0:
FreeCAD.Console.PrintError(str(translate("Arch","Couldn't compute the wall shape")))
return
base = base.removeSplitter()
obj.Shape = base
if not DraftGeomUtils.isNull(pl):

View File

@ -381,6 +381,7 @@ class _Wall(ArchComponent.Component):
else:
base = None
FreeCAD.Console.PrintError(str(translate("Arch","Error: Invalid base object")))
elif obj.Base.isDerivedFrom("Mesh::Feature"):
if obj.Base.Mesh.isSolid():
if obj.Base.Mesh.countComponents() == 1:
@ -392,6 +393,7 @@ class _Wall(ArchComponent.Component):
obj.Base.ViewObject.show()
if base:
for app in obj.Additions:
if Draft.getType(app) == "Window":
# window
@ -427,7 +429,12 @@ class _Wall(ArchComponent.Component):
base = base.cut(hole.Shape)
hole.ViewObject.hide() # to be removed
if not base.isNull():
if base.isValid() and (not base.isNull()) and base.Solids:
if base.Volume < 0:
base.reverse()
if base.Volume < 0:
FreeCAD.Console.PrintError(str(translate("Arch","Couldn't compute the wall shape")))
return
try:
base = base.removeSplitter()
except:

View File

@ -1356,65 +1356,76 @@ def export(objectslist,filename,nospline=False):
"called when freecad exports a file. If nospline=True, bsplines are exported as straight segs"
global exportList
exportList = objectslist
dxf = dxfLibrary.Drawing()
if (len(exportList) == 1) and (exportList[0].isDerivedFrom("Drawing::FeaturePage")):
if (len(exportList) == 1) and (Draft.getType(exportList[0]) == "ArchSectionView"):
# arch view: export it "as is"
dxf = exportList[0].Proxy.getDXF()
if dxf:
f = open(filename,"w")
f.write(dxf)
f.close()
elif (len(exportList) == 1) and (exportList[0].isDerivedFrom("Drawing::FeaturePage")):
# page: special hack-export! (see below)
exportPage(exportList[0],filename)
return
for ob in exportList:
print "processing ",ob.Name
if ob.isDerivedFrom("Part::Feature"):
if not ob.Shape.isNull():
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("dxfmesh"):
writeMesh(ob,dxf)
else:
if ob.Shape.ShapeType == 'Compound':
if (len(ob.Shape.Wires) == 1):
# only one wire in this compound, no lone edge -> polyline
if (len(ob.Shape.Wires[0].Edges) == len(ob.Shape.Edges)):
writeShape(ob,dxf,nospline)
else:
# other cases, treat edges
dxf = dxfLibrary.Drawing()
for ob in exportList:
print "processing ",ob.Name
if ob.isDerivedFrom("Part::Feature"):
if not ob.Shape.isNull():
if FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft").GetBool("dxfmesh"):
writeMesh(ob,dxf)
else:
if ob.Shape.ShapeType == 'Compound':
if (len(ob.Shape.Wires) == 1):
# only one wire in this compound, no lone edge -> polyline
if (len(ob.Shape.Wires[0].Edges) == len(ob.Shape.Edges)):
writeShape(ob,dxf,nospline)
else:
# 1 wire + lone edges -> block
block = getBlock(ob)
dxf.blocks.append(block)
dxf.append(dxfLibrary.Insert(name=ob.Name.upper()))
else:
# 1 wire + lone edges -> block
# all other cases: block
block = getBlock(ob)
dxf.blocks.append(block)
dxf.append(dxfLibrary.Insert(name=ob.Name.upper()))
else:
# all other cases: block
block = getBlock(ob)
dxf.blocks.append(block)
dxf.append(dxfLibrary.Insert(name=ob.Name.upper()))
else:
writeShape(ob,dxf,nospline)
elif (ob.Type == "App::Annotation"):
# texts
# temporary - as dxfLibrary doesn't support mtexts well, we use several single-line texts
# well, anyway, at the moment, Draft only writes single-line texts, so...
for text in ob.LabelText:
point = DraftVecUtils.tup(FreeCAD.Vector(ob.Position.x,
ob.Position.y-ob.LabelText.index(text),
ob.Position.z))
if gui: height = float(ob.ViewObject.FontSize)
else: height = 1
dxf.append(dxfLibrary.Text(text,point,height=height,
color=getACI(ob,text=True),
style='STANDARD',
layer=getGroup(ob,exportList)))
elif 'Dimline' in ob.PropertiesList:
p1 = DraftVecUtils.tup(ob.Start)
p2 = DraftVecUtils.tup(ob.End)
base = Part.Line(ob.Start,ob.End).toShape()
proj = DraftGeomUtils.findDistance(ob.Dimline,base)
if not proj:
pbase = DraftVecUtils.tup(ob.End)
else:
pbase = DraftVecUtils.tup(ob.End.add(DraftVecUtils.neg(proj)))
dxf.append(dxfLibrary.Dimension(pbase,p1,p2,color=getACI(ob),
layer=getGroup(ob,exportList)))
dxf.saveas(filename)
writeShape(ob,dxf,nospline)
elif Draft.getType(ob) == "Annotation":
# texts
# temporary - as dxfLibrary doesn't support mtexts well, we use several single-line texts
# well, anyway, at the moment, Draft only writes single-line texts, so...
for text in ob.LabelText:
point = DraftVecUtils.tup(FreeCAD.Vector(ob.Position.x,
ob.Position.y-ob.LabelText.index(text),
ob.Position.z))
if gui: height = float(ob.ViewObject.FontSize)
else: height = 1
dxf.append(dxfLibrary.Text(text,point,height=height,
color=getACI(ob,text=True),
style='STANDARD',
layer=getGroup(ob,exportList)))
elif Draft.getType(ob) == "Dimension":
p1 = DraftVecUtils.tup(ob.Start)
p2 = DraftVecUtils.tup(ob.End)
base = Part.Line(ob.Start,ob.End).toShape()
proj = DraftGeomUtils.findDistance(ob.Dimline,base)
if not proj:
pbase = DraftVecUtils.tup(ob.End)
else:
pbase = DraftVecUtils.tup(ob.End.add(DraftVecUtils.neg(proj)))
dxf.append(dxfLibrary.Dimension(pbase,p1,p2,color=getACI(ob),
layer=getGroup(ob,exportList)))
dxf.saveas(filename)
FreeCAD.Console.PrintMessage("successfully exported "+filename+"\r\n")
def exportPage(page,filename):