Arch: Window presets

This commit is contained in:
Yorik van Havre
2013-10-17 16:29:47 -03:00
parent bb01ec1605
commit 8781ffb883
17 changed files with 4635 additions and 257 deletions

View File

@@ -23,7 +23,7 @@
import FreeCAD,FreeCADGui,Draft,ArchComponent,DraftVecUtils,ArchCommands
from FreeCAD import Vector
from PyQt4 import QtCore,QtGui
from PyQt4 import QtCore,QtGui,QtSvg
from DraftTools import translate
__title__="FreeCAD Window"
@@ -31,11 +31,14 @@ __author__ = "Yorik van Havre"
__url__ = "http://www.freecadweb.org"
WindowPartTypes = ["Frame","Solid panel","Glass panel"]
AllowedHosts = ["Wall","Structure"]
AllowedHosts = ["Wall","Structure","Roof"]
WindowPresets = ["Fixed", "Open 1-pane", "Open 2-pane", "Sash 2-pane",
"Sliding 2-pane", "Simple door", "Glass door"]
def makeWindow(baseobj=None,width=None,height=None,parts=None,name=str(translate("Arch","Window"))):
'''makeWindow(baseobj,[width,height,parts,name]): creates a window based on the
given base 2D object (sketch or draft).'''
def makeWindow(baseobj=None,width=None,name=str(translate("Arch","Window"))):
'''makeWindow(obj,[name]): creates a window based on the
given object'''
if baseobj:
if Draft.getType(baseobj) == "Window":
obj = Draft.clone(baseobj)
@@ -43,32 +46,306 @@ def makeWindow(baseobj=None,width=None,name=str(translate("Arch","Window"))):
obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name)
_Window(obj)
_ViewProviderWindow(obj.ViewObject)
if width:
obj.Width = width
if height:
obj.Height = height
if baseobj:
obj.Normal = baseobj.Placement.Rotation.multVec(FreeCAD.Vector(0,0,-1))
obj.Base = baseobj
if width:
obj.WindowParts = ["Default","Panel","Wire0",str(width),"0"]
else:
obj.WindowParts = makeDefaultWindowPart(baseobj)
if parts:
obj.WindowParts = parts
else:
if obj.isDerivedFrom("Part::Feature"):
if obj.Shape.Wires:
i = 0
ws = ''
for w in obj.Shape.Wires:
if w.isClosed():
if ws: ws += ","
ws += "Wire" + str(i)
i += 1
obj.WindowParts = ["Default","Frame",ws,"1","0"]
if obj.Base:
obj.Base.ViewObject.DisplayMode = "Wireframe"
obj.Base.ViewObject.hide()
#obj.ViewObject.ShapeColor = ArchCommands.getDefaultColor("Window")
return obj
def makeDefaultWindowPart(obj):
"returns a list of 5 strings defining a default window part from a 2D object"
part = []
if obj.isDerivedFrom("Part::Feature"):
if obj.Shape.Wires:
i = 0
ws = ''
for w in obj.Shape.Wires:
if w.isClosed():
if ws: ws += ","
ws += "Wire" + str(i)
i += 1
part = ["Default","Frame",ws,"1","0"]
return part
def makeWindowPreset(windowtype,width,height,h1,h2,h3,w1,w2,o1,o2,placement=None):
"""makeWindowPreset(windowtype,width,height,h1,h2,h3,w1,w2,o1,o2,[placement]): makes a
window object based on the given data. windowtype must be one of the names
defined in Arch.WindowPresets"""
def makeSketch(windowtype,width,height,h1,h2,h3,w1,w2,o1,o2):
import Part,Sketcher
width = float(width)
height = float(height)
h1 = float(h1)
h2 = float(h2)
h3 = float(h3)
w1 = float(w1)
w2 = float(w2)
o1 = float(o1)
o2 = float(o2)
# small spacing to avoid wrong auto-wires in sketch
tol = h1/10
# glass size divider
gla = 10
s = FreeCAD.ActiveDocument.addObject('Sketcher::SketchObject','Sketch')
def addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8):
"adds two rectangles to the given sketch"
idx = s.GeometryCount
s.addGeometry(Part.Line(p1,p2))
s.addGeometry(Part.Line(p2,p3))
s.addGeometry(Part.Line(p3,p4))
s.addGeometry(Part.Line(p4,p1))
s.addConstraint(Sketcher.Constraint('Coincident',idx,2,idx+1,1))
s.addConstraint(Sketcher.Constraint('Coincident',idx+1,2,idx+2,1))
s.addConstraint(Sketcher.Constraint('Coincident',idx+2,2,idx+3,1))
s.addConstraint(Sketcher.Constraint('Coincident',idx+3,2,idx,1))
s.addConstraint(Sketcher.Constraint('Horizontal',idx))
s.addConstraint(Sketcher.Constraint('Horizontal',idx+2))
s.addConstraint(Sketcher.Constraint('Vertical',idx+1))
s.addConstraint(Sketcher.Constraint('Vertical',idx+3))
s.addGeometry(Part.Line(p5,p6))
s.addGeometry(Part.Line(p6,p7))
s.addGeometry(Part.Line(p7,p8))
s.addGeometry(Part.Line(p8,p5))
s.addConstraint(Sketcher.Constraint('Coincident',idx+4,2,idx+5,1))
s.addConstraint(Sketcher.Constraint('Coincident',idx+5,2,idx+6,1))
s.addConstraint(Sketcher.Constraint('Coincident',idx+6,2,idx+7,1))
s.addConstraint(Sketcher.Constraint('Coincident',idx+7,2,idx+4,1))
s.addConstraint(Sketcher.Constraint('Horizontal',idx+4))
s.addConstraint(Sketcher.Constraint('Horizontal',idx+6))
s.addConstraint(Sketcher.Constraint('Vertical',idx+5))
s.addConstraint(Sketcher.Constraint('Vertical',idx+7))
def outerFrame(s,width,height,h1,w1,o1):
p1 = Vector(0,0,0)
p2 = Vector(width,0,0)
p3 = Vector(width,height,0)
p4 = Vector(0,height,0)
p5 = Vector(h1,h1,0)
p6 = Vector(width-h1,h1,0)
p7 = Vector(width-h1,height-h1,0)
p8 = Vector(h1,height-h1,0)
addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8)
s.addConstraint(Sketcher.Constraint('DistanceY',1,height)) #16
s.addConstraint(Sketcher.Constraint('DistanceX',0,width)) #17
s.addConstraint(Sketcher.Constraint('DistanceY',6,2,2,2,h1))
s.addConstraint(Sketcher.Constraint('DistanceX',2,2,6,2,h1))
s.addConstraint(Sketcher.Constraint('DistanceX',4,2,0,2,h1))
s.addConstraint(Sketcher.Constraint('DistanceY',0,2,4,2,h1))
s.addConstraint(Sketcher.Constraint('Coincident',0,1,-1,1))
return ["OuterFrame","Frame","Wire0,Wire1",str(w1),str(o1)]
def doorFrame(s,width,height,h1,w1,o1):
p1 = Vector(0,0,0)
p2 = Vector(width,0,0)
p3 = Vector(width,height,0)
p4 = Vector(0,height,0)
p5 = Vector(h1,0,0)
p6 = Vector(width-h1,0,0)
p7 = Vector(width-h1,height-h1,0)
p8 = Vector(h1,height-h1,0)
addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8)
s.addConstraint(Sketcher.Constraint('DistanceY',1,height)) #16
s.addConstraint(Sketcher.Constraint('DistanceX',0,width)) #17
s.addConstraint(Sketcher.Constraint('DistanceY',6,2,2,2,h1))
s.addConstraint(Sketcher.Constraint('DistanceX',2,2,6,2,h1))
s.addConstraint(Sketcher.Constraint('DistanceX',4,2,0,2,h1))
s.addConstraint(Sketcher.Constraint('DistanceY',0,2,4,2,0.0))
s.addConstraint(Sketcher.Constraint('Coincident',0,1,-1,1))
return ["OuterFrame","Frame","Wire0,Wire1",str(w1),str(o1)]
if windowtype == "Fixed":
wp = outerFrame(s,width,height,h1,w1,o1)
wp.extend(["Glass","Glass panel","Wire1",str(w1/gla),str(w1/2)])
elif windowtype == "Open 1-pane":
wp = outerFrame(s,width,height,h1,w1,o1)
p1 = Vector(h1+tol,h1+tol,0)
p2 = Vector(width-(h1+tol),h1+tol,0)
p3 = Vector(width-(h1+tol),height-(h1+tol),0)
p4 = Vector(h1+tol,height-(h1+tol),0)
p5 = Vector(h1+h2,h1+h2,0)
p6 = Vector(width-(h1+h2),h1+h2,0)
p7 = Vector(width-(h1+h2),height-(h1+h2),0)
p8 = Vector(h1+h2,height-(h1+h2),0)
addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8)
s.addConstraint(Sketcher.Constraint('DistanceX',8,1,12,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceY',8,1,12,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',14,1,10,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceY',14,1,10,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',4,1,8,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceY',4,1,8,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceX',10,1,6,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceY',10,1,6,1,tol))
wp.extend(["InnerFrame","Frame","Wire2,Wire3",str(w2),str(o1+o2)])
wp.extend(["InnerGlass","Glass panel","Wire3",str(w2/gla),str(o1+o2+w2/2)])
elif windowtype == "Open 2-pane":
wp = outerFrame(s,width,height,h1,w1,o1)
p1 = Vector(h1+tol,h1+tol,0)
p2 = Vector((width/2)-tol,h1+tol,0)
p3 = Vector((width/2)-tol,height-(h1+tol),0)
p4 = Vector(h1+tol,height-(h1+tol),0)
p5 = Vector(h1+h2,h1+h2,0)
p6 = Vector((width/2)-h2,h1+h2,0)
p7 = Vector((width/2)-h2,height-(h1+h2),0)
p8 = Vector(h1+h2,height-(h1+h2),0)
addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8)
p1 = Vector((width/2)+tol,h1+tol,0)
p2 = Vector(width-(h1+tol),h1+tol,0)
p3 = Vector(width-(h1+tol),height-(h1+tol),0)
p4 = Vector((width/2)+tol,height-(h1+tol),0)
p5 = Vector((width/2)+h2,h1+h2,0)
p6 = Vector(width-(h1+h2),h1+h2,0)
p7 = Vector(width-(h1+h2),height-(h1+h2),0)
p8 = Vector((width/2)+h2,height-(h1+h2),0)
addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8)
s.addConstraint(Sketcher.Constraint('DistanceY',8,1,12,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',8,1,12,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',21,2,17,2,h2))
s.addConstraint(Sketcher.Constraint('DistanceY',21,2,17,2,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',16,1,20,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',14,1,10,1,h2))
s.addConstraint(Sketcher.Constraint('Equal',22,14))
s.addConstraint(Sketcher.Constraint('DistanceY',8,2,16,1,0.0))
s.addConstraint(Sketcher.Constraint('DistanceY',10,1,18,2,0.0))
s.addConstraint(Sketcher.Constraint('DistanceX',4,1,8,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceY',4,1,8,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceX',6,1,18,1,-tol))
s.addConstraint(Sketcher.Constraint('DistanceY',6,1,18,1,-tol))
s.addConstraint(Sketcher.Constraint('DistanceX',9,1,19,2,tol))
wp.extend(["LeftFrame","Frame","Wire2,Wire3",str(w2),str(o1+o2)])
wp.extend(["LeftGlass","Glass panel","Wire3",str(w2/gla),str(o1+o2+w2/2)])
wp.extend(["RightFrame","Frame","Wire4,Wire5",str(w2),str(o1+o2)])
wp.extend(["RightGlass","Glass panel","Wire5",str(w2/gla),str(o1+o2+w2/2)])
elif windowtype == "Sash 2-pane":
wp = outerFrame(s,width,height,h1,w1,o1)
p1 = Vector(h1+tol,h1+tol,0)
p2 = Vector(width-(h1+tol),h1+tol,0)
p3 = Vector(width-(h1+tol),(height/2)-tol,0)
p4 = Vector(h1+tol,(height/2)-tol,0)
p5 = Vector(h1+h2,h1+h2,0)
p6 = Vector(width-(h1+h2),h1+h2,0)
p7 = Vector(width-(h1+h2),(height/2)-h2,0)
p8 = Vector(h1+h2,(height/2)-h2,0)
addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8)
p1 = Vector(h1+tol,(height/2)+tol,0)
p2 = Vector(width-(h1+tol),(height/2)+tol,0)
p3 = Vector(width-(h1+tol),height-(h1+tol),0)
p4 = Vector(h1+tol,height-(h1+tol),0)
p5 = Vector(h1+h2,(height/2)+h2,0)
p6 = Vector(width-(h1+h2),(height/2)+h2,0)
p7 = Vector(width-(h1+h2),height-(h1+h2),0)
p8 = Vector(h1+h2,height-(h1+h2),0)
addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8)
s.addConstraint(Sketcher.Constraint('DistanceY',8,1,12,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',8,1,12,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',21,2,17,2,h2))
s.addConstraint(Sketcher.Constraint('DistanceY',21,2,17,2,h2))
s.addConstraint(Sketcher.Constraint('DistanceY',16,2,20,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceY',10,2,14,2,-h2))
s.addConstraint(Sketcher.Constraint('Equal',23,15))
s.addConstraint(Sketcher.Constraint('DistanceX',12,1,20,1,0.0))
s.addConstraint(Sketcher.Constraint('DistanceX',13,2,20,2,0.0))
s.addConstraint(Sketcher.Constraint('DistanceX',4,1,8,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceY',4,1,8,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceX',6,1,18,1,-tol))
s.addConstraint(Sketcher.Constraint('DistanceY',6,1,18,1,-tol))
s.addConstraint(Sketcher.Constraint('DistanceY',10,1,16,1,tol))
wp.extend(["LowerFrame","Frame","Wire2,Wire3",str(w2),str(o1+o2+w2)])
wp.extend(["LowerGlass","Glass panel","Wire3",str(w2/gla),str(o1+o2+w2+w2/2)])
wp.extend(["UpperFrame","Frame","Wire4,Wire5",str(w2),str(o1+o2)])
wp.extend(["UpperGlass","Glass panel","Wire5",str(w2/gla),str(o1+o2+w2/2)])
elif windowtype == "Sliding 2-pane":
wp = outerFrame(s,width,height,h1,w1,o1)
p1 = Vector(h1+tol,h1+tol,0)
p2 = Vector((width/2)-tol,h1+tol,0)
p3 = Vector((width/2)-tol,height-(h1+tol),0)
p4 = Vector(h1+tol,height-(h1+tol),0)
p5 = Vector(h1+h2,h1+h2,0)
p6 = Vector((width/2)-h2,h1+h2,0)
p7 = Vector((width/2)-h2,height-(h1+h2),0)
p8 = Vector(h1+h2,height-(h1+h2),0)
addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8)
p1 = Vector((width/2)+tol,h1+tol,0)
p2 = Vector(width-(h1+tol),h1+tol,0)
p3 = Vector(width-(h1+tol),height-(h1+tol),0)
p4 = Vector((width/2)+tol,height-(h1+tol),0)
p5 = Vector((width/2)+h2,h1+h2,0)
p6 = Vector(width-(h1+h2),h1+h2,0)
p7 = Vector(width-(h1+h2),height-(h1+h2),0)
p8 = Vector((width/2)+h2,height-(h1+h2),0)
addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8)
s.addConstraint(Sketcher.Constraint('DistanceY',8,1,12,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',8,1,12,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',21,2,17,2,h2))
s.addConstraint(Sketcher.Constraint('DistanceY',21,2,17,2,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',16,1,20,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',14,1,10,1,h2))
s.addConstraint(Sketcher.Constraint('Equal',22,14))
s.addConstraint(Sketcher.Constraint('DistanceY',8,2,16,1,0.0))
s.addConstraint(Sketcher.Constraint('DistanceY',10,1,18,2,0.0))
s.addConstraint(Sketcher.Constraint('DistanceX',4,1,8,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceY',4,1,8,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceX',6,1,18,1,-tol))
s.addConstraint(Sketcher.Constraint('DistanceY',6,1,18,1,-tol))
s.addConstraint(Sketcher.Constraint('DistanceX',9,1,19,2,tol))
wp.extend(["LeftFrame","Frame","Wire2,Wire3",str(w2),str(o1+o2)])
wp.extend(["LeftGlass","Glass panel","Wire3",str(w2/gla),str(o1+o2+w2/2)])
wp.extend(["RightFrame","Frame","Wire4,Wire5",str(w2),str(o1+o2+w2)])
wp.extend(["RightGlass","Glass panel","Wire5",str(w2/gla),str(o1+o2+w2+w2/2)])
elif windowtype == "Simple door":
wp = doorFrame(s,width,height,h1,w1,o1)
wp.extend(["Door","Solid panel","Wire1",str(w2),str(o1+o2)])
elif windowtype == "Glass door":
wp = doorFrame(s,width,height,h1,w1,o1)
p1 = Vector(h1+tol,h1+tol,0)
p2 = Vector(width-(h1+tol),h1+tol,0)
p3 = Vector(width-(h1+tol),height-(h1+tol),0)
p4 = Vector(h1+tol,height-(h1+tol),0)
p5 = Vector(h1+h2,h1+h3,0)
p6 = Vector(width-(h1+h2),h1+h3,0)
p7 = Vector(width-(h1+h2),height-(h1+h2),0)
p8 = Vector(h1+h2,height-(h1+h2),0)
addFrame(s,p1,p2,p3,p4,p5,p6,p7,p8)
s.addConstraint(Sketcher.Constraint('DistanceX',8,1,12,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceY',8,1,12,1,h3))
s.addConstraint(Sketcher.Constraint('DistanceX',14,1,10,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceY',14,1,10,1,h2))
s.addConstraint(Sketcher.Constraint('DistanceX',4,1,8,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceY',4,1,8,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceX',10,1,6,1,tol))
s.addConstraint(Sketcher.Constraint('DistanceY',10,1,6,1,tol))
wp.extend(["InnerFrame","Frame","Wire2,Wire3",str(w2),str(o1+o2)])
wp.extend(["InnerGlass","Glass panel","Wire3",str(w2/gla),str(o1+o2+w2/2)])
return (s,wp)
if windowtype in WindowPresets:
default = makeSketch(windowtype,width,height,h1,h2,h3,w1,w2,o1,o2)
FreeCAD.ActiveDocument.recompute()
if default:
if placement:
default[0].Placement = placement
FreeCAD.ActiveDocument.recompute()
obj = makeWindow(default[0],width,height,default[1])
obj.Preset = WindowPresets.index(windowtype)+1
FreeCAD.ActiveDocument.recompute()
return obj
print "Arch: Unknown window type"
class _CommandWindow:
"the Arch Window command definition"
@@ -80,14 +357,29 @@ class _CommandWindow:
def Activated(self):
sel = FreeCADGui.Selection.getSelection()
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch")
self.Thickness = p.GetFloat("WindowThickness",50)
self.Width = p.GetFloat("WindowWidth",1000)
self.Height = p.GetFloat("WindowHeight",1000)
self.Preset = 0
self.baseFace = None
self.wparams = ["Width","Height","H1","H2","H3","W1","W2","O1","O2"]
# auto mode
if sel:
obj = sel[0]
if Draft.getType(obj) in AllowedHosts:
FreeCADGui.activateWorkbench("SketcherWorkbench")
FreeCADGui.runCommand("Sketcher_NewSketch")
FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(obj,FreeCAD.ActiveDocument.Objects[-1],hide=False,nextCommand="Arch_Window")
FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver)
else:
# make sure only one face is selected
sub = FreeCADGui.Selection.getSelectionEx()[0]
if len(sub.SubElementNames) == 1:
if "Face" in sub.SubElementNames[0]:
FreeCADGui.activateWorkbench("SketcherWorkbench")
FreeCADGui.runCommand("Sketcher_NewSketch")
FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(obj,FreeCAD.ActiveDocument.Objects[-1],hide=False,nextCommand="Arch_Window")
FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver)
return
elif obj.isDerivedFrom("Part::Part2DObject"):
FreeCADGui.Control.closeDialog()
host = None
if hasattr(obj,"Support"):
@@ -111,11 +403,162 @@ class _CommandWindow:
FreeCADGui.doCommand("Arch.removeComponents(win,host=FreeCAD.ActiveDocument."+sibling.Name+")")
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
return
# interactive mode
if hasattr(FreeCAD,"DraftWorkingPlane"):
FreeCAD.DraftWorkingPlane.setup()
import DraftTrackers
self.tracker = DraftTrackers.boxTracker()
self.tracker.length(self.Width)
self.tracker.width(self.Thickness)
self.tracker.height(self.Height)
FreeCAD.Console.PrintMessage(str(translate("Arch","Pick a face on an existing object or select a preset")))
FreeCADGui.Snapper.getPoint(callback=self.getPoint,movecallback=self.update,extradlg=self.taskbox())
FreeCADGui.Snapper.setSelectMode(True)
def getPoint(self,point=None,obj=None):
"this function is called by the snapper when it has a 3D point"
self.tracker.finalize()
FreeCADGui.Control.closeDialog()
if point == None:
return
if not self.Preset:
if obj and (self.baseFace != None):
if Draft.getType(obj) in AllowedHosts:
# make sure only one face is selected
FreeCADGui.Selection.clearSelection()
FreeCADGui.Selection.addSelection(obj,"Face"+str(self.baseFace+1))
FreeCADGui.activateWorkbench("SketcherWorkbench")
FreeCADGui.runCommand("Sketcher_NewSketch")
FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(obj,FreeCAD.ActiveDocument.Objects[-1],hide=False,nextCommand="Arch_Window")
FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver)
else:
FreeCAD.Console.PrintMessage(str(translate("Arch","Please select a base object\n")))
FreeCADGui.Control.showDialog(ArchComponent.SelectionTaskPanel())
FreeCAD.ArchObserver = ArchComponent.ArchSelectionObserver(nextCommand="Arch_Window")
FreeCADGui.Selection.addObserver(FreeCAD.ArchObserver)
# preset
FreeCAD.ActiveDocument.openTransaction(str(translate("Arch","Create Window")))
FreeCADGui.doCommand("import math,FreeCAD,Arch,WorkingPlane")
if obj and (self.baseFace != None):
FreeCADGui.doCommand("pl = WorkingPlane.getPlacementFromFace(FreeCAD.ActiveDocument." + obj.Name + ".Shape.Faces[" + str(self.baseFace) + "])")
else:
FreeCADGui.doCommand("m = FreeCAD.Matrix()")
FreeCADGui.doCommand("m.rotateX(math.pi/2)")
FreeCADGui.doCommand("pl = FreeCAD.Placement(m)")
FreeCADGui.doCommand("pl.Base = FreeCAD.Vector(" + str(point.x) + "," + str(point.y) + ","+ str(point.z) + ")")
wp = ""
for p in self.wparams:
wp += p.lower() + "=" + str(getattr(self,p)) + ","
FreeCADGui.doCommand("win = Arch.makeWindowPreset(\"" + WindowPresets[self.Preset-1] + "\"," + wp + "placement=pl)")
if obj:
if Draft.getType(obj) in AllowedHosts:
FreeCADGui.doCommand("Arch.removeComponents(win,host=FreeCAD.ActiveDocument."+obj.Name+")")
siblings = obj.Proxy.getSiblings(obj)
for sibling in siblings:
FreeCADGui.doCommand("Arch.removeComponents(win,host=FreeCAD.ActiveDocument."+sibling.Name+")")
FreeCAD.ActiveDocument.commitTransaction()
FreeCAD.ActiveDocument.recompute()
return
def update(self,point,info):
"this function is called by the Snapper when the mouse is moved"
delta = FreeCAD.Vector(self.Width/2,self.Thickness/2,self.Height/2)
rot = FreeCAD.Rotation()
self.baseFace = None
if info:
if "Face" in info['Component']:
import WorkingPlane
o = FreeCAD.ActiveDocument.getObject(info['Object'])
self.baseFace = int(info['Component'][4:])-1
f = o.Shape.Faces[self.baseFace]
p = WorkingPlane.getPlacementFromFace(f,rotated=True)
if p:
rot = p.Rotation
delta = rot.multVec(FreeCAD.Vector(delta.x,-delta.y,-delta.z))
self.tracker.pos(point.add(delta))
self.tracker.setRotation(rot)
def taskbox(self):
"sets up a taskbox widget"
d = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Units").GetInt("Decimals",2)
w = QtGui.QWidget()
w.setWindowTitle(str(translate("Arch","Window options")))
lay0 = QtGui.QVBoxLayout(w)
# presets box
layp = QtGui.QHBoxLayout()
lay0.addLayout(layp)
labelp = QtGui.QLabel(str(translate("Arch","Preset")))
layp.addWidget(labelp)
valuep = QtGui.QComboBox()
valuep.addItems(["Create from scratch"]+WindowPresets)
valuep.setCurrentIndex(self.Preset)
layp.addWidget(valuep)
QtCore.QObject.connect(valuep,QtCore.SIGNAL("currentIndexChanged(int)"),self.setPreset)
# image display
self.im = QtSvg.QSvgWidget(":/ui/ParametersWindowFixed.svg")
self.im.setMaximumWidth(200)
lay0.addWidget(self.im)
self.im.hide()
# parameters
for param in self.wparams:
l = QtGui.QHBoxLayout()
lay0.addLayout(l)
lab = QtGui.QLabel(str(translate("Arch",param)))
l.addWidget(lab)
setattr(self,"val"+param,QtGui.QDoubleSpinBox())
wid = getattr(self,"val"+param)
wid.setDecimals(d)
wid.setMaximum(99999.99)
if param == "Width":
wid.setValue(self.Width)
elif param == "Height":
wid.setValue(self.Height)
else:
wid.setValue(self.Thickness)
setattr(self,param,self.Thickness)
l.addWidget(wid)
l.setEnabled(False)
QtCore.QObject.connect(getattr(self,"val"+param),QtCore.SIGNAL("valueChanged(double)"),self.setParams)
return w
def setParams(self,d):
for param in self.wparams:
setattr(self,param,float(getattr(self,"val"+param).value()))
self.tracker.length(self.Width)
self.tracker.height(self.Height)
self.tracker.width(self.W1)
def setPreset(self,i):
self.Preset = i
if i > 0:
FreeCADGui.Snapper.setSelectMode(False)
self.tracker.length(self.Width)
self.tracker.width(self.Thickness)
self.tracker.height(self.Height)
self.tracker.on()
if i == 1:
self.im.load(":/ui/ParametersWindowFixed.svg")
elif i == 2:
self.im.load(":/ui/ParametersWindowSimple.svg")
elif i == 7:
self.im.load(":/ui/ParametersDoorGlass.svg")
elif i == 4:
self.im.load(":/ui/ParametersWindowStash.svg")
elif i == 6:
self.im.load(":/ui/ParametersDoorSimple.svg")
else:
self.im.load(":/ui/ParametersWindowDouble.svg")
self.im.show()
for param in self.wparams:
getattr(self,"val"+param).setEnabled(True)
else:
FreeCADGui.Snapper.setSelectMode(True)
self.tracker.off()
self.im.hide()
for param in self.wparams:
getattr(self,"val"+param).setEnabled(False)
class _Window(ArchComponent.Component):
@@ -124,10 +567,19 @@ class _Window(ArchComponent.Component):
ArchComponent.Component.__init__(self,obj)
obj.addProperty("App::PropertyStringList","WindowParts","Arch",
str(translate("Arch","the components of this window")))
obj.addProperty("App::PropertyDistance","HoleDepth","Arch",
obj.addProperty("App::PropertyLength","HoleDepth","Arch",
str(translate("Arch","The depth of the hole that this window makes in its host object. Keep 0 for automatic.")))
obj.addProperty("Part::PropertyPartShape","Subvolume","Arch",
str(translate("Arch","an optional volume to be subtracted from hosts of this window")))
obj.addProperty("App::PropertyLength","Width","Arch",
str(translate("Arch","The width of this window (for preset windows only)")))
obj.addProperty("App::PropertyLength","Height","Arch",
str(translate("Arch","The height of this window (for preset windows only)")))
obj.addProperty("App::PropertyVector","Normal","Arch",
str(translate("Arch","The normal direction of this window")))
obj.addProperty("App::PropertyInteger","Preset","Arch","")
obj.setEditorMode("Preset",2)
self.Type = "Window"
obj.Proxy = self
@@ -135,10 +587,19 @@ class _Window(ArchComponent.Component):
self.hideSubobjects(obj,prop)
if prop in ["Base","WindowParts"]:
self.execute(obj)
elif prop == "HoleDepth":
elif prop in ["HoleDepth"]:
for o in obj.InList:
if Draft.getType(o) in AllowedHosts:
o.Proxy.execute(o)
elif prop in ["Width","Height"]:
if obj.Preset != 0:
if obj.Base:
if prop == "Height":
obj.Base.setDatum(16,obj.Height)
elif prop == "Width":
obj.Base.setDatum(17,obj.Width)
FreeCAD.ActiveDocument.recompute()
def execute(self,obj):
import Part, DraftGeomUtils
@@ -166,6 +627,10 @@ class _Window(ArchComponent.Component):
wires.remove(ext)
shape = Part.Face(ext)
norm = shape.normalAt(0,0)
if hasattr(obj,"Normal"):
if obj.Normal:
if not DraftVecUtils.isNull(obj.Normal):
norm = obj.Normal
thk = float(obj.WindowParts[(i*5)+3])
if thk:
exv = DraftVecUtils.scaleTo(norm,thk)
@@ -185,8 +650,7 @@ class _Window(ArchComponent.Component):
if not DraftGeomUtils.isNull(pl):
base.Placement = pl
elif not obj.WindowParts:
# create default parts
obj.WindowParts = makeDefaultWindowPart(obj.Base)
pass
else:
print "Arch: Bad formatting of window parts definitions"
@@ -195,7 +659,6 @@ class _Window(ArchComponent.Component):
if not base.isNull():
obj.Shape = base
def getSubVolume(self,obj,plac=None):
"returns a subvolume for cutting in a base object"
@@ -244,14 +707,20 @@ class _Window(ArchComponent.Component):
if f:
import Part
f = Part.Face(f)
n = f.normalAt(0,0)
v1 = DraftVecUtils.scaleTo(n,width)
norm = f.normalAt(0,0)
if hasattr(obj,"Normal"):
if obj.Normal:
if not DraftVecUtils.isNull(obj.Normal):
norm = obj.Normal
v1 = DraftVecUtils.scaleTo(norm,width)
f.translate(v1)
v2 = v1.negative()
v2 = Vector(v1).multiply(-2)
f = f.extrude(v2)
if plac:
f.Placement = plac
else:
f.Placement = obj.Placement
return f
return None
@@ -266,7 +735,7 @@ class _ViewProviderWindow(ArchComponent.ViewProviderComponent):
return ":/icons/Arch_Window_Tree.svg"
def updateData(self,obj,prop):
if (prop in ["WindowParts","Shape"]) and obj.ViewObject:
if (prop in ["WindowParts","Shape"]):
if obj.Shape:
if not obj.Shape.isNull():
self.colorize(obj)