Arch: Allow to manually edit structural nodes - issue #2356

This commit is contained in:
Yorik van Havre 2016-10-09 23:15:47 -03:00
parent 9914f3690e
commit e8e10ed05d
4 changed files with 94 additions and 20 deletions

View File

@ -125,8 +125,8 @@ def removeFromComponent(compobject,subobject):
class SelectionTaskPanel:
"""A temp taks panel to wait for a selection"""
def __init__(self):
self.form = QtGui.QLabel()
self.form.setText(QtGui.QApplication.translate("Arch", "Please select a base object", None, QtGui.QApplication.UnicodeUTF8))
self.baseform = QtGui.QLabel()
self.baseform.setText(QtGui.QApplication.translate("Arch", "Please select a base object", None, QtGui.QApplication.UnicodeUTF8))
def getStandardButtons(self):
return int(QtGui.QDialogButtonBox.Cancel)
@ -147,27 +147,28 @@ class ComponentTaskPanel:
self.obj = None
self.attribs = ["Base","Additions","Subtractions","Objects","Components","Axes","Fixtures","Armatures"]
self.form = QtGui.QWidget()
self.form.setObjectName("TaskPanel")
self.grid = QtGui.QGridLayout(self.form)
self.baseform = QtGui.QWidget()
self.baseform.setObjectName("TaskPanel")
self.grid = QtGui.QGridLayout(self.baseform)
self.grid.setObjectName("grid")
self.title = QtGui.QLabel(self.form)
self.title = QtGui.QLabel(self.baseform)
self.grid.addWidget(self.title, 0, 0, 1, 2)
self.form = self.baseform
# tree
self.tree = QtGui.QTreeWidget(self.form)
self.tree = QtGui.QTreeWidget(self.baseform)
self.grid.addWidget(self.tree, 1, 0, 1, 2)
self.tree.setColumnCount(1)
self.tree.header().hide()
# buttons
self.addButton = QtGui.QPushButton(self.form)
self.addButton = QtGui.QPushButton(self.baseform)
self.addButton.setObjectName("addButton")
self.addButton.setIcon(QtGui.QIcon(":/icons/Arch_Add.svg"))
self.grid.addWidget(self.addButton, 3, 0, 1, 1)
self.addButton.setEnabled(False)
self.delButton = QtGui.QPushButton(self.form)
self.delButton = QtGui.QPushButton(self.baseform)
self.delButton.setObjectName("delButton")
self.delButton.setIcon(QtGui.QIcon(":/icons/Arch_Remove.svg"))
self.grid.addWidget(self.delButton, 3, 1, 1, 1)
@ -236,7 +237,7 @@ class ComponentTaskPanel:
item.setIcon(0,self.getIcon(o))
Tattrib.addChild(item)
self.tree.expandItem(Tattrib)
self.retranslateUi(self.form)
self.retranslateUi(self.baseform)
def addElement(self):
it = self.tree.currentItem()
@ -276,7 +277,7 @@ class ComponentTaskPanel:
FreeCADGui.ActiveDocument.setEdit(obj.Name,0)
def retranslateUi(self, TaskPanel):
TaskPanel.setWindowTitle(QtGui.QApplication.translate("Arch", "Components", None, QtGui.QApplication.UnicodeUTF8))
self.baseform.setWindowTitle(QtGui.QApplication.translate("Arch", "Components", None, QtGui.QApplication.UnicodeUTF8))
self.delButton.setText(QtGui.QApplication.translate("Arch", "Remove", None, QtGui.QApplication.UnicodeUTF8))
self.addButton.setText(QtGui.QApplication.translate("Arch", "Add", None, QtGui.QApplication.UnicodeUTF8))
self.title.setText(QtGui.QApplication.translate("Arch", "Components of this object", None, QtGui.QApplication.UnicodeUTF8))

View File

@ -469,10 +469,11 @@ class _Structure(ArchComponent.Component):
def onChanged(self,obj,prop):
self.hideSubobjects(obj,prop)
if prop == "Shape":
if prop in ["Shape","ResetNodes"]:
# ResetNodes is not a property but it allows us to use this function to force reset the nodes
if hasattr(obj,"Nodes"):
# update structural nodes
if obj.Nodes:
if obj.Nodes and (prop != "ResetNodes"):
if hasattr(self,"nodes"):
if self.nodes:
if obj.Nodes != self.nodes:
@ -497,6 +498,18 @@ class _Structure(ArchComponent.Component):
self.nodes = [v.Point for v in nodes.Vertexes]
obj.Nodes = self.nodes
def getNodeEdges(self,obj):
"returns a list of edges from stuctural nodes"
edges = []
if obj.Nodes:
import Part
for i in range(len(obj.Nodes)-1):
edges.append(Part.Line(obj.Placement.multVec(obj.Nodes[i]),obj.Placement.multVec(obj.Nodes[i+1])).toShape())
if hasattr(obj.ViewObject,"NodeType"):
if (obj.ViewObject.NodeType == "Area") and (len(obj.Nodes) > 2):
edges.append(Part.Line(obj.Placement.multVec(obj.Nodes[-1]),obj.Placement.multVec(obj.Nodes[0])).toShape())
return edges
class _ViewProviderStructure(ArchComponent.ViewProviderComponent):
"A View Provider for the Structure object"
@ -600,6 +613,42 @@ class _ViewProviderStructure(ArchComponent.ViewProviderComponent):
self.updateData(vobj.Object,"Nodes")
ArchComponent.ViewProviderComponent.onChanged(self,vobj,prop)
def setEdit(self,vobj,mode):
if mode == 0:
taskd = StructureTaskPanel(vobj.Object)
taskd.obj = self.Object
taskd.update()
FreeCADGui.Control.showDialog(taskd)
return True
return False
class StructureTaskPanel(ArchComponent.ComponentTaskPanel):
def __init__(self,obj):
ArchComponent.ComponentTaskPanel.__init__(self)
self.optwid = QtGui.QWidget()
self.optwid.setWindowTitle(QtGui.QApplication.translate("Arch", "Node Tools", None, QtGui.QApplication.UnicodeUTF8))
lay = QtGui.QVBoxLayout(self.optwid)
self.resetButton = QtGui.QPushButton(self.optwid)
self.resetButton.setIcon(QtGui.QIcon(":/icons/edit-undo.svg"))
self.resetButton.setText(QtGui.QApplication.translate("Arch", "Reset nodes", None, QtGui.QApplication.UnicodeUTF8))
lay.addWidget(self.resetButton)
QtCore.QObject.connect(self.resetButton, QtCore.SIGNAL("clicked()"), self.resetNodes)
self.editButton = QtGui.QPushButton(self.optwid)
self.editButton.setIcon(QtGui.QIcon(":/icons/Draft_Edit.svg"))
self.editButton.setText(QtGui.QApplication.translate("Arch", "Edit nodes", None, QtGui.QApplication.UnicodeUTF8))
lay.addWidget(self.editButton)
QtCore.QObject.connect(self.editButton, QtCore.SIGNAL("clicked()"), self.editNodes)
self.form = [self.form,self.optwid]
self.Object = obj
def editNodes(self):
FreeCADGui.Control.closeDialog()
FreeCADGui.runCommand("Draft_Edit")
def resetNodes(self):
self.Object.Proxy.onChanged(self.Object,"ResetNodes")
class _StructuralSystem(ArchComponent.Component):
"The Structural System object"

View File

@ -268,7 +268,7 @@ class Snapper:
if obj.isDerivedFrom("Part::Feature"):
snaps.extend(self.snapToSpecials(obj))
snaps.extend(self.snapToSpecials(obj,lastpoint,eline))
if Draft.getType(obj) == "Polygon":
# special snapping for polygons: add the center
@ -283,7 +283,6 @@ class Snapper:
snaps.extend(self.snapToEndpoints(edge))
snaps.extend(self.snapToMidpoint(edge))
snaps.extend(self.snapToPerpendicular(edge,lastpoint))
#snaps.extend(self.snapToOrtho(edge,lastpoint,constrain)) # now part of snapToPolar
snaps.extend(self.snapToIntersection(edge))
snaps.extend(self.snapToElines(edge,eline))
@ -700,8 +699,7 @@ class Snapper:
for p in pts:
snaps.append([p,'intersection',self.toWP(p)])
return snaps
def snapToAngles(self,shape):
"returns a list of angle snap locations"
snaps = []
@ -783,7 +781,7 @@ class Snapper:
else:
return []
def snapToSpecials(self,obj):
def snapToSpecials(self,obj,lastpoint=None,eline=None):
"returns special snap locations, if any"
snaps = []
if self.isEnabled("special"):
@ -804,6 +802,13 @@ class Snapper:
else:
b = obj.Placement.Base
snaps.append([b,'special',self.toWP(b)])
if obj.ViewObject.ShowNodes:
for edge in obj.Proxy.getNodeEdges(obj):
snaps.extend(self.snapToEndpoints(edge))
snaps.extend(self.snapToMidpoint(edge))
snaps.extend(self.snapToPerpendicular(edge,lastpoint))
snaps.extend(self.snapToIntersection(edge))
snaps.extend(self.snapToElines(edge,eline))
elif hasattr(obj,"SnapPoints"):
for p in obj.SnapPoints:

View File

@ -3487,6 +3487,18 @@ class Edit(Modifier):
self.editpoints.append(self.obj.ViewObject.Proxy.getTextPosition(self.obj.ViewObject))
except:
pass
elif Draft.getType(self.obj) == "Structure":
if self.obj.Nodes:
self.originalDisplayMode = self.obj.ViewObject.DisplayMode
self.originalPoints = self.obj.ViewObject.NodeSize
self.originalNodes = self.obj.ViewObject.ShowNodes
self.obj.ViewObject.DisplayMode = "Wireframe"
self.obj.ViewObject.NodeSize = 1
self.obj.ViewObject.ShowNodes = True
for p in self.obj.Nodes:
if self.pl:
p = self.pl.multVec(p)
self.editpoints.append(p)
if Draft.getType(self.obj) != "BezCurve":
self.trackers = []
if self.editpoints:
@ -3521,6 +3533,10 @@ class Edit(Modifier):
if self.obj:
if hasattr(self.obj.ViewObject,"Selectable"):
self.obj.ViewObject.Selectable = self.selectstate
if Draft.getType(self.obj) == "Structure":
self.obj.ViewObject.DisplayMode = self.originalDisplayMode
self.obj.ViewObject.NodeSize = self.originalPoints
self.obj.ViewObject.ShowNodes = self.originalNodes
Modifier.finish(self)
plane.restore()
if FreeCADGui.Snapper.grid:
@ -3580,8 +3596,7 @@ class Edit(Modifier):
self.trackers[self.editing].off()
if hasattr(self.obj.ViewObject,"Selectable"):
self.obj.ViewObject.Selectable = False
if "Points" in self.obj.PropertiesList:
self.node.append(self.obj.Points[self.editing])
self.node.append(self.trackers[self.editing].get())
FreeCADGui.Snapper.setSelectMode(False)
else:
self.trackers[self.editing].on()
@ -3703,6 +3718,10 @@ class Edit(Modifier):
elif Draft.getType(self.obj) == "Space":
if self.editing == 0:
self.obj.ViewObject.TextPosition = v
elif Draft.getType(self.obj) == "Structure":
nodes = self.obj.Nodes
nodes[self.editing] = self.invpl.multVec(v)
self.obj.Nodes = nodes
def numericInput(self,v,numy=None,numz=None):
'''this function gets called by the toolbar