Arch: Support for opening symbols - fixes #2353
This commit is contained in:
@@ -85,7 +85,7 @@ def getSVG(section,allOn=False,renderMode="Wireframe",showHidden=False,showFill=
|
||||
|
||||
if not section.Objects:
|
||||
return
|
||||
import DraftGeomUtils
|
||||
import Part,DraftGeomUtils
|
||||
p = FreeCAD.Placement(section.Placement)
|
||||
direction = p.Rotation.multVec(FreeCAD.Vector(0,0,1))
|
||||
objs = Draft.getGroupContents(section.Objects,walls=True,addgroups=True)
|
||||
@@ -95,6 +95,7 @@ def getSVG(section,allOn=False,renderMode="Wireframe",showHidden=False,showFill=
|
||||
spaces = []
|
||||
nonspaces = []
|
||||
drafts = []
|
||||
windows = []
|
||||
cutface = None
|
||||
for o in objs:
|
||||
if Draft.getType(o) == "Space":
|
||||
@@ -105,6 +106,8 @@ def getSVG(section,allOn=False,renderMode="Wireframe",showHidden=False,showFill=
|
||||
drafts.append(o)
|
||||
else:
|
||||
nonspaces.append(o)
|
||||
if Draft.getType(o) == "Window":
|
||||
windows.append(o)
|
||||
objs = nonspaces
|
||||
svg = ''
|
||||
fillpattern = '<pattern id="sectionfill" patternUnits="userSpaceOnUse" patternTransform="matrix(5,0,0,5,0,0)"'
|
||||
@@ -238,6 +241,32 @@ def getSVG(section,allOn=False,renderMode="Wireframe",showHidden=False,showFill=
|
||||
svg += Draft.getSVG(s,scale=scale,linewidth=linewidth,fontsize=fontsize,direction=direction,techdraw=techdraw,rotation=rotation)
|
||||
if not techdraw:
|
||||
svg += '</g>'
|
||||
# add additional edge symbols from windows
|
||||
if cutface and windows:
|
||||
cutwindows = [w.Name for w in windows if w.Shape.BoundBox.intersect(cutface.BoundBox)]
|
||||
if windows:
|
||||
sh = []
|
||||
for w in windows:
|
||||
if not hasattr(w.Proxy,"sshapes"):
|
||||
w.Proxy.execute(w)
|
||||
if hasattr(w.Proxy,"sshapes"):
|
||||
if w.Proxy.sshapes and (w.Name in cutwindows):
|
||||
c = Part.makeCompound(w.Proxy.sshapes)
|
||||
c.Placement = w.Placement
|
||||
sh.append(c)
|
||||
if hasattr(w.Proxy,"vshapes"):
|
||||
if w.Proxy.vshapes:
|
||||
c = Part.makeCompound(w.Proxy.vshapes)
|
||||
c.Placement = w.Placement
|
||||
sh.append(c)
|
||||
if sh:
|
||||
if not techdraw:
|
||||
svg += '<g transform="scale(1,-1)">'
|
||||
for s in sh:
|
||||
svg += Draft.getSVG(s,scale=scale,linewidth=linewidth,fontsize=fontsize,fillstyle="none",direction=direction,techdraw=techdraw,rotation=rotation)
|
||||
if not techdraw:
|
||||
svg += '</g>'
|
||||
|
||||
#print "complete node:",svg
|
||||
return svg
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ WindowPartTypes = ["Frame","Solid panel","Glass panel","Louvre"]
|
||||
AllowedHosts = ["Wall","Structure","Roof"]
|
||||
WindowPresets = ["Fixed", "Open 1-pane", "Open 2-pane", "Sash 2-pane",
|
||||
"Sliding 2-pane", "Simple door", "Glass door"]
|
||||
WindowOpeningModes = ["None","Arc 90","Arc 90 inv","Arc 45","Arc 45 inv","Arc 180","Arc 180 inv","Triangle","Triangle inv","Sliding","Sliding inv"]
|
||||
Roles = ["Window","Door"]
|
||||
|
||||
|
||||
@@ -370,6 +371,7 @@ def makeWindowPreset(windowtype,width,height,h1,h2,h3,w1,w2,o1,o2,placement=None
|
||||
obj.Placement = FreeCAD.Placement() # unable to find where this bug comes from...
|
||||
if "door" in windowtype:
|
||||
obj.Role = "Door"
|
||||
obj.Label = translate("Arch","Door")
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
return obj
|
||||
|
||||
@@ -639,7 +641,7 @@ class _Window(ArchComponent.Component):
|
||||
obj.addProperty("App::PropertyLength","LouvreWidth","Louvres",QT_TRANSLATE_NOOP("App::Property","the width of louvre elements"))
|
||||
obj.addProperty("App::PropertyLength","LouvreSpacing","Louvres",QT_TRANSLATE_NOOP("App::Property","the space between louvre elements"))
|
||||
obj.setEditorMode("Preset",2)
|
||||
|
||||
obj.setEditorMode("WindowParts",2)
|
||||
self.Type = "Window"
|
||||
obj.Role = Roles
|
||||
obj.Proxy = self
|
||||
@@ -685,6 +687,8 @@ class _Window(ArchComponent.Component):
|
||||
import Part,DraftGeomUtils,math
|
||||
pl = obj.Placement
|
||||
base = None
|
||||
self.sshapes = []
|
||||
self.vshapes = []
|
||||
if obj.Base:
|
||||
if obj.Base.isDerivedFrom("Part::Feature"):
|
||||
if hasattr(obj,"WindowParts"):
|
||||
@@ -692,12 +696,21 @@ class _Window(ArchComponent.Component):
|
||||
shapes = []
|
||||
for i in range(len(obj.WindowParts)/5):
|
||||
wires = []
|
||||
hinge = None
|
||||
omode = None
|
||||
ssymbols = []
|
||||
vsymbols = []
|
||||
wstr = obj.WindowParts[(i*5)+2].split(',')
|
||||
for s in wstr:
|
||||
j = int(s[4:])
|
||||
if obj.Base.Shape.Wires:
|
||||
if len(obj.Base.Shape.Wires) >= j:
|
||||
wires.append(obj.Base.Shape.Wires[j])
|
||||
if "Wire" in s:
|
||||
j = int(s[4:])
|
||||
if obj.Base.Shape.Wires:
|
||||
if len(obj.Base.Shape.Wires) >= j:
|
||||
wires.append(obj.Base.Shape.Wires[j])
|
||||
elif "Edge" in s:
|
||||
hinge = int(s[4:])-1
|
||||
elif "Mode" in s:
|
||||
omode = int(s[-1])
|
||||
if wires:
|
||||
max_length = 0
|
||||
for w in wires:
|
||||
@@ -711,6 +724,88 @@ class _Window(ArchComponent.Component):
|
||||
if obj.Normal:
|
||||
if not DraftVecUtils.isNull(obj.Normal):
|
||||
norm = obj.Normal
|
||||
if hinge and omode:
|
||||
e = obj.Base.Shape.Edges[hinge]
|
||||
ev1 = e.Vertexes[0].Point
|
||||
ev2 = e.Vertexes[-1].Point
|
||||
if ev2.z < ev1.z:
|
||||
ev1,ev2 = ev2,ev1
|
||||
p = None
|
||||
d = 0
|
||||
for v in shape.Vertexes:
|
||||
dist = v.Point.distanceToLine(ev1,ev2.sub(ev1))
|
||||
if dist > d:
|
||||
d = dist
|
||||
p = v.Point
|
||||
if p:
|
||||
chord = p.sub(ev1)
|
||||
enorm = ev2.sub(ev1)
|
||||
proj = DraftVecUtils.project(chord,enorm)
|
||||
if proj.Length > 0:
|
||||
v1 = ev1.add(proj)
|
||||
chord = p.sub(v1)
|
||||
else:
|
||||
v1 = e.Vertexes[0].Point
|
||||
v4 = p.add(DraftVecUtils.scale(enorm,0.5))
|
||||
if omode == 1: # Arc 90,"Arc 90 inv","Arc 45","Arc 45 inv","Arc 180","Arc 180 inv","Triangle","Triangle inv","Sliding","Sliding inv"
|
||||
v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/4,enorm))
|
||||
v3 = v1.add(DraftVecUtils.rotate(chord,math.pi/2,enorm))
|
||||
ssymbols.append(Part.Arc(p,v2,v3).toShape())
|
||||
ssymbols.append(Part.Line(v3,v1).toShape())
|
||||
vsymbols.append(Part.Line(v1,v4).toShape())
|
||||
vsymbols.append(Part.Line(v4,ev2).toShape())
|
||||
elif omode == 2: # Arc -90
|
||||
v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/4,enorm))
|
||||
v3 = v1.add(DraftVecUtils.rotate(chord,-math.pi/2,enorm))
|
||||
ssymbols.append(Part.Arc(p,v2,v3).toShape())
|
||||
ssymbols.append(Part.Line(v3,v1).toShape())
|
||||
vsymbols.append(Part.Line(v1,v4).toShape())
|
||||
vsymbols.append(Part.Line(v4,ev2).toShape())
|
||||
elif omode == 3: # Arc 45
|
||||
v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/8,enorm))
|
||||
v3 = v1.add(DraftVecUtils.rotate(chord,math.pi/4,enorm))
|
||||
ssymbols.append(Part.Arc(p,v2,v3).toShape())
|
||||
ssymbols.append(Part.Line(v3,v1).toShape())
|
||||
vsymbols.append(Part.Line(v1,v4).toShape())
|
||||
vsymbols.append(Part.Line(v4,ev2).toShape())
|
||||
elif omode == 4: # Arc -45
|
||||
v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/8,enorm))
|
||||
v3 = v1.add(DraftVecUtils.rotate(chord,-math.pi/4,enorm))
|
||||
ssymbols.append(Part.Arc(p,v2,v3).toShape())
|
||||
ssymbols.append(Part.Line(v3,v1).toShape())
|
||||
vsymbols.append(Part.Line(v1,v4).toShape())
|
||||
vsymbols.append(Part.Line(v4,ev2).toShape())
|
||||
elif omode == 5: # Arc 180
|
||||
v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/2,enorm))
|
||||
v3 = v1.add(DraftVecUtils.rotate(chord,math.pi,enorm))
|
||||
ssymbols.append(Part.Arc(p,v2,v3).toShape())
|
||||
ssymbols.append(Part.Line(v3,v1).toShape())
|
||||
vsymbols.append(Part.Line(v1,v4).toShape())
|
||||
vsymbols.append(Part.Line(v4,ev2).toShape())
|
||||
elif omode == 6: # Arc -180
|
||||
v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/2,enorm))
|
||||
v3 = v1.add(DraftVecUtils.rotate(chord,-math.pi,enorm))
|
||||
ssymbols.append(Part.Arc(p,v2,v3).toShape())
|
||||
ssymbols.append(Part.Line(v3,v1).toShape())
|
||||
vsymbols.append(Part.Line(v1,v4).toShape())
|
||||
vsymbols.append(Part.Line(v4,ev2).toShape())
|
||||
elif omode == 7: # tri
|
||||
v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/2,enorm))
|
||||
ssymbols.append(Part.Line(p,v2).toShape())
|
||||
ssymbols.append(Part.Line(v2,v1).toShape())
|
||||
vsymbols.append(Part.Line(v1,v4).toShape())
|
||||
vsymbols.append(Part.Line(v4,ev2).toShape())
|
||||
elif omode == 8: # -tri
|
||||
v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/2,enorm))
|
||||
ssymbols.append(Part.Line(p,v2).toShape())
|
||||
ssymbols.append(Part.Line(v2,v1).toShape())
|
||||
vsymbols.append(Part.Line(v1,v4).toShape())
|
||||
vsymbols.append(Part.Line(v4,ev2).toShape())
|
||||
elif omode == 9: # sliding
|
||||
pass
|
||||
elif omode == 10: # -sliding
|
||||
pass
|
||||
|
||||
thk = float(obj.WindowParts[(i*5)+3])
|
||||
if thk:
|
||||
exv = DraftVecUtils.scaleTo(norm,thk)
|
||||
@@ -724,6 +819,10 @@ class _Window(ArchComponent.Component):
|
||||
if zof:
|
||||
zov = DraftVecUtils.scaleTo(norm,zof)
|
||||
shape.translate(zov)
|
||||
for symb in ssymbols:
|
||||
symb.translate(zov)
|
||||
for symb in vsymbols:
|
||||
symb.translate(zov)
|
||||
if obj.WindowParts[(i*5)+1] == "Louvre":
|
||||
if hasattr(obj,"LouvreWidth"):
|
||||
if obj.LouvreWidth and obj.LouvreSpacing:
|
||||
@@ -743,6 +842,8 @@ class _Window(ArchComponent.Component):
|
||||
self.boxes.translate(shape.BoundBox.Center.sub(self.boxes.BoundBox.Center))
|
||||
shape = shape.common(self.boxes)
|
||||
shapes.append(shape)
|
||||
self.sshapes.extend(ssymbols)
|
||||
self.vshapes.extend(vsymbols)
|
||||
if shapes:
|
||||
base = Part.makeCompound(shapes)
|
||||
elif not obj.WindowParts:
|
||||
@@ -756,6 +857,8 @@ class _Window(ArchComponent.Component):
|
||||
base = self.processSubShapes(obj,base)
|
||||
if base:
|
||||
if not base.isNull():
|
||||
if self.sshapes:
|
||||
base = Part.makeCompound([base]+self.sshapes+self.vshapes)
|
||||
self.applyShape(obj,base,pl,allowinvalid=True,allownosolid=True)
|
||||
if hasattr(obj,"Area"):
|
||||
obj.Area = obj.Width.Value * obj.Height.Value
|
||||
@@ -961,11 +1064,15 @@ class _ArchWindowTaskPanel:
|
||||
self.new3 = QtGui.QLabel(self.form)
|
||||
self.new4 = QtGui.QLabel(self.form)
|
||||
self.new5 = QtGui.QLabel(self.form)
|
||||
self.new6 = QtGui.QLabel(self.form)
|
||||
self.new7 = QtGui.QLabel(self.form)
|
||||
self.field1 = QtGui.QLineEdit(self.form)
|
||||
self.field2 = QtGui.QComboBox(self.form)
|
||||
self.field3 = QtGui.QLineEdit(self.form)
|
||||
self.field4 = ui.createWidget("Gui::InputField")
|
||||
self.field5 = ui.createWidget("Gui::InputField")
|
||||
self.field6 = QtGui.QPushButton(self.form)
|
||||
self.field7 = QtGui.QComboBox(self.form)
|
||||
self.createButton = QtGui.QPushButton(self.form)
|
||||
self.createButton.setObjectName("createButton")
|
||||
self.createButton.setIcon(QtGui.QIcon(":/icons/Arch_Add.svg"))
|
||||
@@ -980,13 +1087,19 @@ class _ArchWindowTaskPanel:
|
||||
self.grid.addWidget(self.field4, 10, 2, 1, 5)
|
||||
self.grid.addWidget(self.new5, 11, 0, 1, 1)
|
||||
self.grid.addWidget(self.field5, 11, 2, 1, 5)
|
||||
self.grid.addWidget(self.createButton, 12, 0, 1, 7)
|
||||
self.grid.addWidget(self.new6, 12, 0, 1, 1)
|
||||
self.grid.addWidget(self.field6, 12, 2, 1, 5)
|
||||
self.grid.addWidget(self.new7, 13, 0, 1, 1)
|
||||
self.grid.addWidget(self.field7, 13, 2, 1, 5)
|
||||
self.grid.addWidget(self.createButton, 14, 0, 1, 7)
|
||||
self.newtitle.setVisible(False)
|
||||
self.new1.setVisible(False)
|
||||
self.new2.setVisible(False)
|
||||
self.new3.setVisible(False)
|
||||
self.new4.setVisible(False)
|
||||
self.new5.setVisible(False)
|
||||
self.new6.setVisible(False)
|
||||
self.new7.setVisible(False)
|
||||
self.field1.setVisible(False)
|
||||
self.field2.setVisible(False)
|
||||
for t in WindowPartTypes:
|
||||
@@ -995,6 +1108,10 @@ class _ArchWindowTaskPanel:
|
||||
self.field3.setReadOnly(True)
|
||||
self.field4.setVisible(False)
|
||||
self.field5.setVisible(False)
|
||||
self.field6.setVisible(False)
|
||||
self.field7.setVisible(False)
|
||||
for t in WindowOpeningModes:
|
||||
self.field7.addItem("")
|
||||
self.createButton.setVisible(False)
|
||||
|
||||
QtCore.QObject.connect(self.addButton, QtCore.SIGNAL("clicked()"), self.addElement)
|
||||
@@ -1003,6 +1120,7 @@ class _ArchWindowTaskPanel:
|
||||
QtCore.QObject.connect(self.createButton, QtCore.SIGNAL("clicked()"), self.create)
|
||||
QtCore.QObject.connect(self.comptree, QtCore.SIGNAL("itemClicked(QTreeWidgetItem*,int)"), self.check)
|
||||
QtCore.QObject.connect(self.wiretree, QtCore.SIGNAL("itemClicked(QTreeWidgetItem*,int)"), self.select)
|
||||
QtCore.QObject.connect(self.field6, QtCore.SIGNAL("clicked()"), self.addEdge)
|
||||
self.update()
|
||||
|
||||
FreeCADGui.Selection.clearSelection()
|
||||
@@ -1081,11 +1199,15 @@ class _ArchWindowTaskPanel:
|
||||
self.new3.setVisible(True)
|
||||
self.new4.setVisible(True)
|
||||
self.new5.setVisible(True)
|
||||
self.new6.setVisible(True)
|
||||
self.new7.setVisible(True)
|
||||
self.field1.setVisible(True)
|
||||
self.field2.setVisible(True)
|
||||
self.field3.setVisible(True)
|
||||
self.field4.setVisible(True)
|
||||
self.field5.setVisible(True)
|
||||
self.field6.setVisible(True)
|
||||
self.field7.setVisible(True)
|
||||
self.createButton.setVisible(True)
|
||||
self.addButton.setEnabled(False)
|
||||
self.editButton.setEnabled(False)
|
||||
@@ -1121,6 +1243,18 @@ class _ArchWindowTaskPanel:
|
||||
f.setCurrentIndex(WindowPartTypes.index(t))
|
||||
else:
|
||||
f.setCurrentIndex(0)
|
||||
elif i == 2:
|
||||
wires = []
|
||||
for l in t.split(","):
|
||||
if "Wire" in l:
|
||||
wires.append(l)
|
||||
elif "Edge" in l:
|
||||
self.field6.setText(l)
|
||||
elif "Mode" in l:
|
||||
self.field7.setCurrentIndex(int(l[-1]))
|
||||
if wires:
|
||||
f.setText(",".join(wires))
|
||||
|
||||
elif i in [3,4]:
|
||||
f.setProperty("text",FreeCAD.Units.Quantity(float(t),FreeCAD.Units.Length).UserString)
|
||||
else:
|
||||
@@ -1153,6 +1287,12 @@ class _ArchWindowTaskPanel:
|
||||
t = str(q.Value)
|
||||
except (ValueError,TypeError):
|
||||
ok = False
|
||||
if i == 2:
|
||||
# check additional opening parameters
|
||||
hinge = self.field6.property("text")
|
||||
n = self.field7.currentIndex()
|
||||
if (hinge.startswith("Edge")) and (n > 0):
|
||||
t += "," + hinge + ",Mode" + str(n)
|
||||
ar.append(t)
|
||||
|
||||
if ok:
|
||||
@@ -1175,13 +1315,24 @@ class _ArchWindowTaskPanel:
|
||||
self.new3.setVisible(False)
|
||||
self.new4.setVisible(False)
|
||||
self.new5.setVisible(False)
|
||||
self.new6.setVisible(False)
|
||||
self.new7.setVisible(False)
|
||||
self.field1.setVisible(False)
|
||||
self.field2.setVisible(False)
|
||||
self.field3.setVisible(False)
|
||||
self.field4.setVisible(False)
|
||||
self.field5.setVisible(False)
|
||||
self.field6.setVisible(False)
|
||||
self.field7.setVisible(False)
|
||||
self.createButton.setVisible(False)
|
||||
self.addButton.setEnabled(True)
|
||||
|
||||
def addEdge(self):
|
||||
for sel in FreeCADGui.Selection.getSelectionEx():
|
||||
for sub in sel.SubElementNames:
|
||||
if "Edge" in sub:
|
||||
self.field6.setText(sub)
|
||||
return
|
||||
|
||||
def reject(self):
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
@@ -1203,8 +1354,14 @@ class _ArchWindowTaskPanel:
|
||||
self.new3.setText(QtGui.QApplication.translate("Arch", "Wires", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.new4.setText(QtGui.QApplication.translate("Arch", "Thickness", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.new5.setText(QtGui.QApplication.translate("Arch", "Z offset", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.new6.setText(QtGui.QApplication.translate("Arch", "Hinge", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.new7.setText(QtGui.QApplication.translate("Arch", "Opening mode", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.field6.setText(QtGui.QApplication.translate("Arch", "Get selected edge", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.field6.setToolTip(QtGui.QApplication.translate("Arch", "Press to retrieve the selected edge", None, QtGui.QApplication.UnicodeUTF8))
|
||||
for i in range(len(WindowPartTypes)):
|
||||
self.field2.setItemText(i, QtGui.QApplication.translate("Arch", WindowPartTypes[i], None, QtGui.QApplication.UnicodeUTF8))
|
||||
for i in range(len(WindowOpeningModes)):
|
||||
self.field7.setItemText(i, QtGui.QApplication.translate("Arch", WindowOpeningModes[i], None, QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
FreeCADGui.addCommand('Arch_Window',_CommandWindow())
|
||||
|
||||
Reference in New Issue
Block a user