From 7fc56ca973ff6ba7ecad273bcb53b8db3e1ea65d Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Mon, 5 Jun 2017 20:06:01 -0300 Subject: [PATCH] Arch: Added Axis System --- src/Mod/Arch/ArchAxis.py | 289 +++++++++++++++++++++++++++++++++++++-- src/Mod/Arch/InitGui.py | 2 +- 2 files changed, 281 insertions(+), 10 deletions(-) diff --git a/src/Mod/Arch/ArchAxis.py b/src/Mod/Arch/ArchAxis.py index 4d58798b07..121ba95eb3 100644 --- a/src/Mod/Arch/ArchAxis.py +++ b/src/Mod/Arch/ArchAxis.py @@ -48,8 +48,9 @@ __url__ = "http://www.freecadweb.org" # This module provides tools to build axis systems # An axis system is a collection of planar axes with a number/tag + def makeAxis(num=5,size=1000,name="Axes"): - '''makeAxis(num,size): makes an Axis System + '''makeAxis(num,size): makes an Axis set based on the given number of axes and interval distances''' obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython",name) obj.Label = translate("Arch",name) @@ -67,29 +68,67 @@ def makeAxis(num=5,size=1000,name="Axes"): FreeCAD.ActiveDocument.recompute() return obj + +def makeAxisSystem(axes,name="Axis System"): + '''makeAxisSystem(axes): makes a system from the given list of axes''' + if not isinstance(axes,list): + axes = [axes] + obj = FreeCAD.ActiveDocument.addObject("App::FeaturePython",name) + obj.Label = translate("Arch",name) + _AxisSystem(obj) + obj.Axes = axes + if FreeCAD.GuiUp: + _ViewProviderAxisSystem(obj.ViewObject) + + class _CommandAxis: "the Arch Axis command definition" def GetResources(self): return {'Pixmap' : 'Arch_Axis', 'MenuText': QT_TRANSLATE_NOOP("Arch_Axis","Axis"), 'Accel': "A, X", - 'ToolTip': QT_TRANSLATE_NOOP("Arch_Axis","Creates an axis system.")} + 'ToolTip': QT_TRANSLATE_NOOP("Arch_Axis","Creates a set of axes.")} def Activated(self): FreeCAD.ActiveDocument.openTransaction(translate("Arch","Create Axis")) FreeCADGui.addModule("Arch") - sel = FreeCADGui.Selection.getSelection() - st = Draft.getObjectsOfType(sel,"Structure") - if st: - FreeCADGui.doCommand("axe = Arch.makeAxis()") - FreeCADGui.doCommand("Arch.makeStructuralSystem(" + ArchCommands.getStringList(st) + ",[axe])") - else: - FreeCADGui.doCommand("Arch.makeAxis()") + + FreeCADGui.doCommand("Arch.makeAxis()") FreeCAD.ActiveDocument.commitTransaction() def IsActive(self): return not FreeCAD.ActiveDocument is None + +class _CommandAxisSystem: + "the Arch Axis System command definition" + def GetResources(self): + return {'Pixmap' : 'Arch_Axis_System', + 'MenuText': QT_TRANSLATE_NOOP("Arch_AxisSystem","Axis System"), + 'Accel': "X, S", + 'ToolTip': QT_TRANSLATE_NOOP("Arch_AxisSystem","Creates an axis system from a set of axes.")} + + def Activated(self): + if FreeCADGui.Selection.getSelection(): + import Draft + s = "[" + for o in FreeCADGui.Selection.getSelection(): + if Draft.getType(o) != "Axis": + FreeCAD.Console.PrintError(translate("Arch","Only axes must be selected\n")) + return + s += "FreeCAD.ActiveDocument."+o.Name+"," + s += "]" + FreeCAD.ActiveDocument.openTransaction(translate("Arch","Create Axis System")) + FreeCADGui.addModule("Arch") + FreeCADGui.doCommand("Arch.makeAxisSystem("+s+")") + FreeCAD.ActiveDocument.commitTransaction() + else: + FreeCAD.Console.PrintError(translate("Arch","Please select at least one axis\n")) + + def IsActive(self): + return not FreeCAD.ActiveDocument is None + + class _Axis: "The Axis object" def __init__(self,obj): @@ -135,6 +174,14 @@ class _Axis: if state: self.Type = state + def getPoints(self,obj): + "returns the gridpoints of linked axes" + pts = [] + for e in obj.Shape.Edges: + pts.append(e.Vertexes[0].Point) + return pts + + class _ViewProviderAxis: "A View Provider for the Axis object" @@ -575,5 +622,229 @@ class _AxisTaskPanel: QtGui.QApplication.translate("Arch", "Angle", None), QtGui.QApplication.translate("Arch", "Label", None)]) + +class _AxisSystem: + "The Axis System object" + def __init__(self,obj): + obj.addProperty("App::PropertyLinkList","Axes","Arch", QT_TRANSLATE_NOOP("App::Property","The axes this system is made of")) + obj.addProperty("App::PropertyPlacement","Placement","Base","") + self.Type = "AxisSystem" + obj.Proxy = self + + def execute(self,obj): + pass + + def onBeforeChange(self,obj,prop): + if prop == "Placement": + self.Placement = obj.Placement + + def onChanged(self,obj,prop): + if prop == "Placement": + if hasattr(self,"Placement"): + delta = obj.Placement.multiply(self.Placement.inverse()) + for o in obj.Axes: + o.Placement = delta.multiply(o.Placement) + + def __getstate__(self): + return self.Type + + def __setstate__(self,state): + if state: + self.Type = state + + def getPoints(self,obj): + "returns the gridpoints of linked axes" + import DraftGeomUtils + pts = [] + if len(obj.Axes) == 1: + for e in obj.Axes[0].Shape.Edges: + pts.append(e.Vertexes[0].Point) + elif len(obj.Axes) == 2: + set1 = obj.Axes[0].Shape.Edges # X + set2 = obj.Axes[1].Shape.Edges # Y + for e1 in set1: + for e2 in set2: + pts.extend(DraftGeomUtils.findIntersection(e1,e2)) + elif len(obj.Axes) == 3: + set1 = obj.Axes[0].Shape.Edges # X + set2 = obj.Axes[1].Shape.Edges # Y + set3 = obj.Axes[2].Shape.Edges # Z + bset = [] + cv = None + for e1 in set1: + for e2 in set2: + bset.extend(DraftGeomUtils.findIntersection(e1,e2)) + for e3 in set3: + if not cv: + cv = e3.Vertexes[0].Point + pts.extend(bset) + else: + cv = e3.Vertexes[0].Point.sub(vc) + pts.extend([p.add(cv) for p in bset]) + return pts + + +class _ViewProviderAxisSystem: + "A View Provider for the Axis object" + + def __init__(self,vobj): + vobj.Proxy = self + + def getIcon(self): + import Arch_rc + return ":/icons/Arch_Axis_System_Tree.svg" + + def claimChildren(self): + if hasattr(self,"axes"): + return self.axes + return [] + + def attach(self, vobj): + self.axes = vobj.Object.Axes + + def getDisplayModes(self,vobj): + return ["Default"] + + def getDefaultDisplayMode(self): + return "Default" + + def setDisplayMode(self,mode): + return mode + + def updateData(self,obj,prop): + self.axes = obj.Axes + + def onChanged(self, vobj, prop): + if prop == "Visibility": + for o in vobj.Object.Axes: + o.ViewObject.Visibility = vobj.Visibility + + def setEdit(self,vobj,mode=0): + taskd = AxisSystemTaskPanel(vobj.Object) + FreeCADGui.Control.showDialog(taskd) + return True + + def unsetEdit(self,vobj,mode): + FreeCADGui.Control.closeDialog() + return + + def doubleClicked(self,vobj): + self.setEdit(vobj) + + def __getstate__(self): + return None + + def __setstate__(self,state): + return None + + +class AxisSystemTaskPanel: + '''A TaskPanel for all the section plane object''' + def __init__(self,obj): + + self.obj = obj + self.form = QtGui.QWidget() + self.form.setObjectName("Axis System") + self.grid = QtGui.QGridLayout(self.form) + self.grid.setObjectName("grid") + self.title = QtGui.QLabel(self.form) + self.grid.addWidget(self.title, 0, 0, 1, 2) + + # tree + self.tree = QtGui.QTreeWidget(self.form) + 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.setObjectName("addButton") + self.addButton.setIcon(QtGui.QIcon(":/icons/Arch_Add.svg")) + self.grid.addWidget(self.addButton, 3, 0, 1, 1) + + self.delButton = QtGui.QPushButton(self.form) + self.delButton.setObjectName("delButton") + self.delButton.setIcon(QtGui.QIcon(":/icons/Arch_Remove.svg")) + self.grid.addWidget(self.delButton, 3, 1, 1, 1) + + QtCore.QObject.connect(self.addButton, QtCore.SIGNAL("clicked()"), self.addElement) + QtCore.QObject.connect(self.delButton, QtCore.SIGNAL("clicked()"), self.removeElement) + self.update() + + def isAllowedAlterSelection(self): + return True + + def isAllowedAlterView(self): + return True + + def getStandardButtons(self): + return int(QtGui.QDialogButtonBox.Ok) + + def getIcon(self,obj): + if hasattr(obj.ViewObject,"Proxy"): + return QtGui.QIcon(obj.ViewObject.Proxy.getIcon()) + elif obj.isDerivedFrom("Sketcher::SketchObject"): + return QtGui.QIcon(":/icons/Sketcher_Sketch.svg") + elif obj.isDerivedFrom("App::DocumentObjectGroup"): + return QtGui.QApplication.style().standardIcon(QtGui.QStyle.SP_DirIcon) + else: + return QtGui.QIcon(":/icons/Tree_Part.svg") + + def update(self): + self.tree.clear() + if self.obj: + for o in self.obj.Axes: + item = QtGui.QTreeWidgetItem(self.tree) + item.setText(0,o.Label) + item.setToolTip(0,o.Name) + item.setIcon(0,self.getIcon(o)) + self.retranslateUi(self.form) + + def addElement(self): + if self.obj: + for o in FreeCADGui.Selection.getSelection(): + if (not(o in self.obj.Axes)) and (o != self.obj): + g = self.obj.Axes + g.append(o) + self.obj.Axes = g + self.update() + + def removeElement(self): + if self.obj: + it = self.tree.currentItem() + if it: + o = FreeCAD.ActiveDocument.getObject(str(it.toolTip(0))) + if o in self.obj.Axes: + g = self.obj.Axes + g.remove(o) + self.obj.Axes = g + self.update() + + def accept(self): + FreeCAD.ActiveDocument.recompute() + FreeCADGui.ActiveDocument.resetEdit() + return True + + def retranslateUi(self, TaskPanel): + TaskPanel.setWindowTitle(QtGui.QApplication.translate("Arch", "Axes", None)) + self.delButton.setText(QtGui.QApplication.translate("Arch", "Remove", None)) + self.addButton.setText(QtGui.QApplication.translate("Arch", "Add", None)) + self.title.setText(QtGui.QApplication.translate("Arch", "Axis system components", None)) + + if FreeCAD.GuiUp: FreeCADGui.addCommand('Arch_Axis',_CommandAxis()) + FreeCADGui.addCommand('Arch_AxisSystem',_CommandAxisSystem()) + + class _ArchAxisGroupCommand: + + def GetCommands(self): + return tuple(['Arch_Axis','Arch_AxisSystem']) + def GetResources(self): + return { 'MenuText': QT_TRANSLATE_NOOP("Arch_AxisTools",'Axis tools'), + 'ToolTip': QT_TRANSLATE_NOOP("Arch_AxisTools",'Axis tools') + } + def IsActive(self): + return not FreeCAD.ActiveDocument is None + + FreeCADGui.addCommand('Arch_AxisTools', _ArchAxisGroupCommand()) diff --git a/src/Mod/Arch/InitGui.py b/src/Mod/Arch/InitGui.py index dad05aea6d..7d64c159c8 100644 --- a/src/Mod/Arch/InitGui.py +++ b/src/Mod/Arch/InitGui.py @@ -35,7 +35,7 @@ class ArchWorkbench(Workbench): # arch tools self.archtools = ["Arch_Wall","Arch_Structure","Arch_Rebar", "Arch_Floor","Arch_Building","Arch_Site", - "Arch_Window","Arch_Roof","Arch_Axis", + "Arch_Window","Arch_Roof","Arch_AxisTools", "Arch_SectionPlane","Arch_Space","Arch_Stairs", "Arch_PanelTools","Arch_Equipment", "Arch_Frame","Arch_MaterialTools","Arch_Schedule","Arch_PipeTools",