#*************************************************************************** #* Copyright (c) 2011 Yorik van Havre * #* * #* This program is free software; you can redistribute it and/or modify * #* it under the terms of the GNU Lesser General Public License (LGPL) * #* as published by the Free Software Foundation; either version 2 of * #* the License, or (at your option) any later version. * #* for detail see the LICENCE text file. * #* * #* This program is distributed in the hope that it will be useful, * #* but WITHOUT ANY WARRANTY; without even the implied warranty of * #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * #* GNU Library General Public License for more details. * #* * #* You should have received a copy of the GNU Library General Public * #* License along with this program; if not, write to the Free Software * #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * #* USA * #* * #*************************************************************************** import FreeCAD import DraftGeomUtils if FreeCAD.GuiUp: import FreeCADGui import Draft from PySide import QtCore, QtGui from draftutils.translate import translate from pivy import coin from PySide.QtCore import QT_TRANSLATE_NOOP else: # \cond def translate(ctxt,txt): return txt def QT_TRANSLATE_NOOP(ctxt,txt): return txt # \endcond __title__ = "FreeCAD Axis System" __author__ = "Yorik van Havre" __url__ = "https://www.freecad.org" ## @package ArchAxisSystem # \ingroup ARCH # \brief Axis system for the Arch workbench # # This module provides tools to build axis systems # An axis system is a collection of multiple axes class _AxisSystem: "The Axis System object" def __init__(self,obj): obj.Proxy = self self.setProperties(obj) def setProperties(self,obj): pl = obj.PropertiesList if not "Axes" in pl: obj.addProperty("App::PropertyLinkList","Axes","AxisSystem", QT_TRANSLATE_NOOP("App::Property","The axes this system is made of")) if not "Placement" in pl: obj.addProperty("App::PropertyPlacement","Placement","AxisSystem",QT_TRANSLATE_NOOP("App::Property","The placement of this axis system")) self.Type = "AxisSystem" def onDocumentRestored(self,obj): self.setProperties(obj) 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 dumps(self): return None def loads(self,state): return None def getPoints(self,obj): "returns the gridpoints of linked axes" 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: v = e3.Vertexes[0].Point.sub(cv) pts.extend([p.add(v) for p in bset]) return pts def getAxisData(self,obj): data = [] for axis in obj.Axes: if hasattr(axis,"Proxy") and hasattr(axis.Proxy,"getAxisData"): data.append(axis.Proxy.getAxisData(axis)) return data 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.Object = vobj.Object self.axes = vobj.Object.Axes vobj.addDisplayMode(coin.SoSeparator(),"Default") 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): if mode != 0: return None taskd = AxisSystemTaskPanel(vobj.Object) FreeCADGui.Control.showDialog(taskd) return True def unsetEdit(self, vobj, mode): if mode != 0: return None FreeCADGui.Control.closeDialog() return True def doubleClicked(self, vobj): self.edit() def setupContextMenu(self, vobj, menu): actionEdit = QtGui.QAction(translate("Arch", "Edit"), menu) QtCore.QObject.connect(actionEdit, QtCore.SIGNAL("triggered()"), self.edit) menu.addAction(actionEdit) def edit(self): FreeCADGui.ActiveDocument.setEdit(self.Object, 0) def dumps(self): return None def loads(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 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) elif hasattr(obj.ViewObject, "Icon"): return QtGui.QIcon(obj.ViewObject.Icon) return QtGui.QIcon(":/icons/Part_3D_object.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))