From 76be63b8b8998562afebe0633cad0ea50a591bc5 Mon Sep 17 00:00:00 2001 From: shai Date: Thu, 28 Nov 2024 19:46:34 +0200 Subject: [PATCH] Add task panel for corner relief --- Resources/panels/CornerReliefPanel.ui | 383 +++++++++++-- SheetMetalCornerReliefCmd.py | 139 ++++- SheetMetalExtendCmd.py | 34 +- SheetMetalRelief.py | 757 +++++++++++++------------- SheetMetalTools.py | 5 +- 5 files changed, 858 insertions(+), 460 deletions(-) diff --git a/Resources/panels/CornerReliefPanel.ui b/Resources/panels/CornerReliefPanel.ui index 987ef20..54cd1c7 100644 --- a/Resources/panels/CornerReliefPanel.ui +++ b/Resources/panels/CornerReliefPanel.ui @@ -6,8 +6,8 @@ 0 0 - 677 - 565 + 403 + 676 @@ -15,44 +15,25 @@ - - - QFrame::StyledPanel - - - QFrame::Raised + + + 0 - - - - - Relief Size - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - + + + Select + + + true + + + false + + + + + Qt::Horizontal @@ -64,57 +45,334 @@ - - - - Relief Type - - - - - - + + + + + + + 0 + 0 + + + + + 16777215 + 120 + + + + true + + + + Name + + + + + SubElement + + + + + + + + + 0 + 0 + + + + Relief Type + + + + - + Circular true + + groupReliefType + - + Square + + groupReliefType + - + - Scaling + Sketch + + groupReliefType + + + + + + + + 0 + 0 + + + + + 0 + + + 4 + + + 0 + + + 4 + + + + + Sketch + + + true + + + + + + + + + + + 0 + 0 + + + + X Offset + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + Y Offset + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + 0 + 0 + + + + Relief Size + + + + - + - Scale Factor + Absolute + + groupReliefSize + - + + + Relative + + + groupReliefSize + + - - - + + + + + + 0 + 0 + + + + + 0 + + + 4 + + + 0 + + + 4 + + + + + + 0 + 0 + + + + Relief Size + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + 0 + + + 4 + + + 0 + + + 4 + + + + + Scale Factor + + + + + + + + 0 + 0 + + + + + + + + + + + + + K Factor + + + + + + + + 0 + 0 + + + + 1.000000000000000 + + + 0.010000000000000 + + + + + + + + + + 0 + 0 + + @@ -145,7 +403,16 @@ Gui::QuantitySpinBox
Gui/PrefWidgets.h
+ + Gui::DoubleSpinBox + QWidget +
gui::doublespinbox.h
+
+ + + + diff --git a/SheetMetalCornerReliefCmd.py b/SheetMetalCornerReliefCmd.py index d795575..de7309c 100644 --- a/SheetMetalCornerReliefCmd.py +++ b/SheetMetalCornerReliefCmd.py @@ -27,6 +27,7 @@ from SheetMetalLogger import SMLogger smEpsilon = SheetMetalTools.smEpsilon +smCornerReliefDefaults = {} def smthk(obj, foldface): normal = foldface.normalAt(0, 0) @@ -249,7 +250,7 @@ def smCornerR( xoffset=0.0, yoffset=0.0, kfactor=0.5, - sketch="", + sketch=None, flipped=False, selEdgeNames="", MainObject=None, @@ -282,7 +283,10 @@ def smCornerR( ) reliefFace = Part.Face(sketch) else: - reliefFace = Part.Face(sketch.Shape.Wires[0]) + if sketch is None: + FreeCAD.Console.PrintError("Sketch object is missing, please select one\n") + return resultSolid + reliefFace = Part.Face(sketch.Shape.Wires[0]).translate(FreeCAD.Vector(xoffset, yoffset, 0)) # Part.show(reliefFace,'reliefFace') # To check face direction @@ -536,9 +540,7 @@ def dumps(self): def loads(self, state): if state is not None: - import FreeCAD - - doc = FreeCAD.ActiveDocument # crap + doc = FreeCAD.ActiveDocument self.Object = doc.getObject(state["ObjectName"]) def claimChildren(self): @@ -551,6 +553,17 @@ def claimChildren(self): def getIcon(self): return os.path.join(icons_path, "SheetMetal_AddCornerRelief.svg") + def setEdit(self, vobj, mode): + taskd = SMCornerReliefTaskPanel(vobj.Object) + FreeCAD.ActiveDocument.openTransaction("Corner Relief") + Gui.Control.showDialog(taskd) + return True + + def unsetEdit(self, vobj, mode): + Gui.Control.closeDialog() + self.Object.baseObject[0].ViewObject.Visibility = False + self.Object.ViewObject.Visibility = True + return False class SMCornerReliefPDVP: "A View provider that nests children objects under the created one" @@ -589,9 +602,7 @@ def dumps(self): def loads(self, state): if state is not None: - import FreeCAD - - doc = FreeCAD.ActiveDocument # crap + doc = FreeCAD.ActiveDocument self.Object = doc.getObject(state["ObjectName"]) def claimChildren(self): @@ -603,6 +614,95 @@ def claimChildren(self): def getIcon(self): return os.path.join(icons_path, "SheetMetal_AddCornerRelief.svg") + def setEdit(self, vobj, mode): + taskd = SMCornerReliefTaskPanel(vobj.Object) + FreeCAD.ActiveDocument.openTransaction("Corner Relief") + Gui.Control.showDialog(taskd) + return True + + def unsetEdit(self, vobj, mode): + Gui.Control.closeDialog() + self.Object.baseObject[0].ViewObject.Visibility = False + self.Object.ViewObject.Visibility = True + return False + + + class SMCornerReliefTaskPanel: + """ A TaskPanel for the Sheetmetal corner relief function""" + + def __init__(self, obj): + self.obj = obj + self.form = SheetMetalTools.taskLoadUI("CornerReliefPanel.ui") + self.updateForm() + SheetMetalTools.taskPopulateSelectionList( + self.form.tree, self.obj.baseObject) + SheetMetalTools.taskConnectSelection( + self.form.AddRemove, self.form.tree, self.obj, ["Edge"]) + SheetMetalTools.taskConnectSelectionSingle( + self, self.form.pushSketch, self.form.txtSketch, obj, "Sketch", ("Sketcher::SketchObject", [])) + SheetMetalTools.taskConnectSpin(self, self.form.unitReliefSize, "Size") + SheetMetalTools.taskConnectSpin(self, self.form.floatScaleFactor, "SizeRatio") + SheetMetalTools.taskConnectSpin(self, self.form.floatKFactor, "kfactor") + SheetMetalTools.taskConnectSpin(self, self.form.unitXOffset, "XOffset") + SheetMetalTools.taskConnectSpin(self, self.form.unitYOffset, "YOffset") + self.form.groupReliefType.buttonToggled.connect(self.reliefTypeChanged) + self.form.groupReliefSize.buttonToggled.connect(self.reliefSizingTypeChanged) + + def updateForm(self): + reliefType = self.obj.ReliefSketch + if reliefType in ["Circle", "Circle-Scaled"]: + self.form.radioCircular.setChecked(True) + elif reliefType in ["Square", "Square-Scaled"]: + self.form.radioSquare.setChecked(True) + else: + self.form.radioSketch.setChecked(True) + + if reliefType in ["Square-Scaled", "Circle-Scaled"]: + self.form.radioRelative.setChecked(True) + else: + self.form.radioAbsolute.setChecked(True) + self.updateWidgetVisibility() + + def reliefTypeChanged(self, button, checked): + if not checked: + return + relative = self.form.radioRelative.isChecked() + if button == self.form.radioCircular: + self.obj.ReliefSketch = "Circle-Scaled" if relative else "Circle" + elif button == self.form.radioSquare: + self.obj.ReliefSketch = "Square-Scaled" if relative else "Square" + else: + self.obj.ReliefSketch = "Sketch" + self.updateWidgetVisibility() + self.obj.Document.recompute() + + def reliefSizingTypeChanged(self, button, checked): + if not checked: + return + curTypeButton = self.form.groupReliefType.checkedButton() + self.reliefTypeChanged(curTypeButton, True) + + def updateWidgetVisibility(self): + self.form.frameScaleFactor.setVisible(self.form.radioRelative.isChecked()) + self.form.frameReliefSize.setVisible(self.form.radioAbsolute.isChecked()) + self.form.groupSketch.setVisible(self.form.radioSketch.isChecked()) + + + def isAllowedAlterSelection(self): + return True + + def isAllowedAlterView(self): + return True + + def accept(self): + SheetMetalTools.taskAccept(self, self.form.AddRemove) + SheetMetalTools.taskSaveDefaults(self.obj, smCornerReliefDefaults, + ["Size", "SizeRatio", "kfactor"]) + return True + + def reject(self): + SheetMetalTools.taskReject(self, self.form.AddRemove) + class AddCornerReliefCommandClass: """Add Corner Relief command""" @@ -635,18 +735,21 @@ def Activated(self): return doc.openTransaction("Corner Relief") if activeBody is None or not SheetMetalTools.smIsPartDesign(selobj): - a = doc.addObject("Part::FeaturePython", "CornerRelief") - SMCornerRelief(a, selobj, sel.SubElementNames) - SMCornerReliefVP(a.ViewObject) + newObj = doc.addObject("Part::FeaturePython", "CornerRelief") + SMCornerRelief(newObj, selobj, sel.SubElementNames) + SMCornerReliefVP(newObj.ViewObject) else: # FreeCAD.Console.PrintLog("found active body: " + activeBody.Name) - a = doc.addObject("PartDesign::FeaturePython", "CornerRelief") - SMCornerRelief(a, selobj, sel.SubElementNames) - SMCornerReliefPDVP(a.ViewObject) - activeBody.addObject(a) - SheetMetalTools.SetViewConfig(a, viewConf) + newObj = doc.addObject("PartDesign::FeaturePython", "CornerRelief") + SMCornerRelief(newObj, selobj, sel.SubElementNames) + SMCornerReliefPDVP(newObj.ViewObject) + activeBody.addObject(newObj) + SheetMetalTools.SetViewConfig(newObj, viewConf) + Gui.Selection.clearSelection() + newObj.baseObject[0].ViewObject.Visibility = False + dialog = SMCornerReliefTaskPanel(newObj) doc.recompute() - doc.commitTransaction() + Gui.Control.showDialog(dialog) return def IsActive(self): @@ -657,7 +760,7 @@ def IsActive(self): return False # selobj = Gui.Selection.getSelection()[0] for selVertex in Gui.Selection.getSelectionEx()[0].SubObjects: - if type(selVertex) != Part.Edge: + if not isinstance(selVertex, Part.Edge): return False return True diff --git a/SheetMetalExtendCmd.py b/SheetMetalExtendCmd.py index 7d957af..d73a5e3 100644 --- a/SheetMetalExtendCmd.py +++ b/SheetMetalExtendCmd.py @@ -396,12 +396,12 @@ def setupContextMenu(self, viewObject, menu): return False def startDefaultEditMode(self, viewObject): - document = viewObject.Document.Document - if not document.HasPendingTransaction: - text = FreeCAD.Qt.translate("QObject", "Edit %1").replace( - "%1", viewObject.Object.Label - ) - document.openTransaction(text) + # document = viewObject.Document.Document + # if not document.HasPendingTransaction: + # text = FreeCAD.Qt.translate("QObject", "Edit %1").replace( + # "%1", viewObject.Object.Label + # ) + # document.openTransaction(text) viewObject.Document.setEdit(viewObject.Object, 0) def updateData(self, fp, prop): @@ -430,9 +430,7 @@ def dumps(self): def loads(self, state): if state is not None: - import FreeCAD - - doc = FreeCAD.ActiveDocument # crap + doc = FreeCAD.ActiveDocument self.Object = doc.getObject(state["ObjectName"]) def claimChildren(self): @@ -448,6 +446,7 @@ def getIcon(self): def setEdit(self, vobj, mode): taskd = SMExtendWallTaskPanel(vobj.Object) + FreeCAD.ActiveDocument.openTransaction("Extend") Gui.Control.showDialog(taskd) return True @@ -494,9 +493,7 @@ def dumps(self): def loads(self, state): if state is not None: - import FreeCAD - - doc = FreeCAD.ActiveDocument # crap + doc = FreeCAD.ActiveDocument self.Object = doc.getObject(state["ObjectName"]) def claimChildren(self): @@ -508,8 +505,21 @@ def claimChildren(self): def getIcon(self): return os.path.join(icons_path, "SheetMetal_Extrude.svg") + def setupContextMenu(self, viewObject, menu): + action = menu.addAction( + FreeCAD.Qt.translate("QObject", "Edit %1").replace( + "%1", viewObject.Object.Label + ) + ) + action.triggered.connect(lambda: self.startDefaultEditMode(viewObject)) + return False + + def startDefaultEditMode(self, viewObject): + viewObject.Document.setEdit(viewObject.Object, 0) + def setEdit(self, vobj, mode): taskd = SMExtendWallTaskPanel(vobj.Object) + FreeCAD.ActiveDocument.openTransaction("Extend") Gui.Control.showDialog(taskd) return True diff --git a/SheetMetalRelief.py b/SheetMetalRelief.py index e2268fe..9a80651 100644 --- a/SheetMetalRelief.py +++ b/SheetMetalRelief.py @@ -1,135 +1,144 @@ -# -*- coding: utf-8 -*- -############################################################################### -# -# SheetMetalRelief.py -# -# Copyright 2015 Shai Seger -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU Lesser General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -# MA 02110-1301, USA. -# -# +# -*- coding: utf-8 -*- +############################################################################### +# +# SheetMetalRelief.py +# +# Copyright 2015 Shai Seger +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# +# ############################################################################### -import FreeCAD, Part, os, SheetMetalTools +import FreeCAD +import Part +import os +import SheetMetalTools # IMPORTANT: please remember to change the element map version in case of any # changes in modeling logic smElementMapVersion = 'sm1.' smEpsilon = SheetMetalTools.smEpsilon + def smMakeFace(vertex, face, edges, relief): - if edges[0].Vertexes[0].isSame(vertex) : - Edgedir1 = edges[0].Vertexes[1].Point - edges[0].Vertexes[0].Point - else : - Edgedir1 = edges[0].Vertexes[0].Point - edges[0].Vertexes[1].Point - Edgedir1.normalize() - - if edges[1].Vertexes[0].isSame(vertex) : - Edgedir2 = edges[1].Vertexes[1].Point - edges[1].Vertexes[0].Point - else : - Edgedir2 = edges[1].Vertexes[0].Point - edges[1].Vertexes[1].Point - Edgedir2.normalize() - normal = face.normalAt(0,0) - Edgedir3 = normal.cross(Edgedir1) - Edgedir4 = normal.cross(Edgedir2) - - p1 = vertex.Point - p2 = p1 + relief * Edgedir1 - p3 = p2 + relief * Edgedir3 - if not(face.isInside(p3,0.0,True)) : - p3 = p2 + relief * Edgedir3 * -1 - p6 = p1 + relief * Edgedir2 - p5 = p6 + relief * Edgedir4 - if not(face.isInside(p5, 0.0,True)) : - p5 = p6 + relief * Edgedir4 * -1 - #print([p1,p2,p3,p5,p6,p1]) - - e1 = Part.makeLine(p2, p3) - #Part.show(e1,'e1') - e2 = Part.makeLine(p5, p6) - #Part.show(e2,'e2') - section = e1.section(e2) - #Part.show(section1,'section1') - - if section.Vertexes : - wire = Part.makePolygon([p1,p2,p3,p6,p1]) - else : - p41 = p3 + relief * Edgedir1 * -1 - p42 = p5 + relief * Edgedir2 * -1 - e1 = Part.Line(p3, p41).toShape() - #Part.show(e1,'e1') - e2 = Part.Line(p42, p5).toShape() - #Part.show(e2,'e2') + if edges[0].Vertexes[0].isSame(vertex): + Edgedir1 = edges[0].Vertexes[1].Point - edges[0].Vertexes[0].Point + else: + Edgedir1 = edges[0].Vertexes[0].Point - edges[0].Vertexes[1].Point + Edgedir1.normalize() + + if edges[1].Vertexes[0].isSame(vertex): + Edgedir2 = edges[1].Vertexes[1].Point - edges[1].Vertexes[0].Point + else: + Edgedir2 = edges[1].Vertexes[0].Point - edges[1].Vertexes[1].Point + Edgedir2.normalize() + normal = face.normalAt(0, 0) + Edgedir3 = normal.cross(Edgedir1) + Edgedir4 = normal.cross(Edgedir2) + + p1 = vertex.Point + p2 = p1 + relief * Edgedir1 + p3 = p2 + relief * Edgedir3 + if not (face.isInside(p3, 0.0, True)): + p3 = p2 + relief * Edgedir3 * -1 + p6 = p1 + relief * Edgedir2 + p5 = p6 + relief * Edgedir4 + if not (face.isInside(p5, 0.0, True)): + p5 = p6 + relief * Edgedir4 * -1 + # print([p1,p2,p3,p5,p6,p1]) + + e1 = Part.makeLine(p2, p3) + # Part.show(e1,'e1') + e2 = Part.makeLine(p5, p6) + # Part.show(e2,'e2') section = e1.section(e2) - #Part.show(section1,'section1') - p4 = section.Vertexes[0].Point - wire = Part.makePolygon([p1,p2,p3,p4,p5,p6,p1]) + # Part.show(section1,'section1') + + if section.Vertexes: + wire = Part.makePolygon([p1, p2, p3, p6, p1]) + else: + p41 = p3 + relief * Edgedir1 * -1 + p42 = p5 + relief * Edgedir2 * -1 + e1 = Part.Line(p3, p41).toShape() + # Part.show(e1,'e1') + e2 = Part.Line(p42, p5).toShape() + # Part.show(e2,'e2') + section = e1.section(e2) + # Part.show(section1,'section1') + p4 = section.Vertexes[0].Point + wire = Part.makePolygon([p1, p2, p3, p4, p5, p6, p1]) - extface = Part.Face(wire) - return extface + extface = Part.Face(wire) + return extface -def smRelief(relief = 2.0, selVertexNames = ' ', MainObject = None): - resultSolid = MainObject - for selVertexName in selVertexNames: - vertex = MainObject.getElement(SheetMetalTools.getElementFromTNP(selVertexName)) - facelist = MainObject.ancestorsOfType(vertex, Part.Face) +def smRelief(relief=2.0, selVertexNames=' ', MainObject=None): - extsolidlist = [] - for face in facelist : - #Part.show(face,'face') - edgelist =face.ancestorsOfType(vertex, Part.Edge) - #for edge in edgelist : - #Part.show(edge,'edge') - extface = smMakeFace(vertex, face, edgelist, relief) - #Part.show(extface,'extface') - extsolid = extface.extrude(relief * face.normalAt(0,0)*-1) - extsolidlist.append(extsolid) + resultSolid = MainObject + for selVertexName in selVertexNames: + vertex = MainObject.getElement( + SheetMetalTools.getElementFromTNP(selVertexName)) + facelist = MainObject.ancestorsOfType(vertex, Part.Face) - cutsolid = extsolidlist[0].multiFuse(extsolidlist[1:]) - #Part.show(cutsolid,'cutsolid') - cutsolid = cutsolid.removeSplitter() - resultSolid = resultSolid.cut(cutsolid) - #Part.show(resultsolid,'resultsolid') + extsolidlist = [] + for face in facelist: + # Part.show(face,'face') + edgelist = face.ancestorsOfType(vertex, Part.Edge) + # for edge in edgelist : + # Part.show(edge,'edge') + extface = smMakeFace(vertex, face, edgelist, relief) + # Part.show(extface,'extface') + extsolid = extface.extrude(relief * face.normalAt(0, 0)*-1) + extsolidlist.append(extsolid) - return resultSolid + cutsolid = extsolidlist[0].multiFuse(extsolidlist[1:]) + # Part.show(cutsolid,'cutsolid') + cutsolid = cutsolid.removeSplitter() + resultSolid = resultSolid.cut(cutsolid) + # Part.show(resultsolid,'resultsolid') + + return resultSolid class SMRelief: - def __init__(self, obj): - '''"Add Relief to Solid" ''' - selobj = Gui.Selection.getSelectionEx()[0] - _tip_ = FreeCAD.Qt.translate("App::Property","Relief Size") - obj.addProperty("App::PropertyLength","relief","Parameters",_tip_).relief = 2.0 - _tip_ = FreeCAD.Qt.translate("App::Property","Base Object") - obj.addProperty("App::PropertyLinkSub", "baseObject", "Parameters",_tip_).baseObject = (selobj.Object, selobj.SubElementNames) - obj.Proxy = self - - def getElementMapVersion(self, _fp, ver, _prop, restored): - if not restored: - return smElementMapVersion + ver - - def execute(self, fp): - '''"Print a short message when doing a recomputation, this method is mandatory" ''' - # pass selected object shape - Main_Object = fp.baseObject[0].Shape.copy() - s = smRelief(relief = fp.relief.Value, selVertexNames = fp.baseObject[1], MainObject = Main_Object) - fp.Shape = s - SheetMetalTools.smHideObjects(fp.baseObject[0]) + def __init__(self, obj): + '''"Add Relief to Solid" ''' + selobj = Gui.Selection.getSelectionEx()[0] + _tip_ = FreeCAD.Qt.translate("App::Property", "Relief Size") + obj.addProperty("App::PropertyLength", "relief", + "Parameters", _tip_).relief = 2.0 + _tip_ = FreeCAD.Qt.translate("App::Property", "Base Object") + obj.addProperty("App::PropertyLinkSub", "baseObject", "Parameters", + _tip_).baseObject = (selobj.Object, selobj.SubElementNames) + obj.Proxy = self + + def getElementMapVersion(self, _fp, ver, _prop, restored): + if not restored: + return smElementMapVersion + ver + + def execute(self, fp): + '''"Print a short message when doing a recomputation, this method is mandatory" ''' + # pass selected object shape + Main_Object = fp.baseObject[0].Shape.copy() + s = smRelief(relief=fp.relief.Value, + selVertexNames=fp.baseObject[1], MainObject=Main_Object) + fp.Shape = s + SheetMetalTools.smHideObjects(fp.baseObject[0]) ########################################################################################################## @@ -139,291 +148,297 @@ def execute(self, fp): if SheetMetalTools.isGuiLoaded(): from PySide import QtCore, QtGui from FreeCAD import Gui - + icons_path = SheetMetalTools.icons_path - + # add translations path Gui.addLanguagePath(SheetMetalTools.language_path) Gui.updateLocale() - - + class SMReliefViewProviderTree: - "A View provider that nests children objects under the created one" - - def __init__(self, obj): - obj.Proxy = self - self.Object = obj.Object - - def attach(self, obj): - self.Object = obj.Object - return - - def setupContextMenu(self, viewObject, menu): - action = menu.addAction(FreeCAD.Qt.translate("QObject", "Edit %1").replace("%1", viewObject.Object.Label)) - action.triggered.connect(lambda: self.startDefaultEditMode(viewObject)) - return False - - def startDefaultEditMode(self, viewObject): - document = viewObject.Document.Document - if not document.HasPendingTransaction: - text = FreeCAD.Qt.translate("QObject", "Edit %1").replace("%1", viewObject.Object.Label) - document.openTransaction(text) - viewObject.Document.setEdit(viewObject.Object, 0) - - def updateData(self, fp, prop): - return - - def getDisplayModes(self,obj): - modes=[] - return modes - - def setDisplayMode(self,mode): - return mode - - def onChanged(self, vp, prop): - return - - def __getstate__(self): - # return {'ObjectName' : self.Object.Name} - return None - - def __setstate__(self, state): - self.loads(state) - - # dumps and loads replace __getstate__ and __setstate__ post v. 0.21.2 - def dumps(self): - return None - - def loads(self, state): - if state is not None: - import FreeCAD - doc = FreeCAD.ActiveDocument #crap - self.Object = doc.getObject(state['ObjectName']) - - def claimChildren(self): - objs = [] - if hasattr(self.Object,"baseObject"): - objs.append(self.Object.baseObject[0]) - return objs - - def getIcon(self): - return os.path.join( icons_path , 'SheetMetal_AddRelief.svg') - - def setEdit(self,vobj,mode): - taskd = SMReliefTaskPanel() - taskd.obj = vobj.Object - taskd.update() - self.Object.ViewObject.Visibility=False - self.Object.baseObject[0].ViewObject.Visibility=True - Gui.Control.showDialog(taskd) - return True - - def unsetEdit(self,vobj,mode): - Gui.Control.closeDialog() - self.Object.baseObject[0].ViewObject.Visibility=False - self.Object.ViewObject.Visibility=True - return False - + "A View provider that nests children objects under the created one" + + def __init__(self, obj): + obj.Proxy = self + self.Object = obj.Object + + def attach(self, obj): + self.Object = obj.Object + return + + def setupContextMenu(self, viewObject, menu): + action = menu.addAction(FreeCAD.Qt.translate( + "QObject", "Edit %1").replace("%1", viewObject.Object.Label)) + action.triggered.connect( + lambda: self.startDefaultEditMode(viewObject)) + return False + + def startDefaultEditMode(self, viewObject): + document = viewObject.Document.Document + if not document.HasPendingTransaction: + text = FreeCAD.Qt.translate("QObject", "Edit %1").replace( + "%1", viewObject.Object.Label) + document.openTransaction(text) + viewObject.Document.setEdit(viewObject.Object, 0) + + def updateData(self, fp, prop): + return + + def getDisplayModes(self, obj): + modes = [] + return modes + + def setDisplayMode(self, mode): + return mode + + def onChanged(self, vp, prop): + return + + def __getstate__(self): + # return {'ObjectName' : self.Object.Name} + return None + + def __setstate__(self, state): + self.loads(state) + + # dumps and loads replace __getstate__ and __setstate__ post v. 0.21.2 + def dumps(self): + return None + + def loads(self, state): + if state is not None: + import FreeCAD + doc = FreeCAD.ActiveDocument # crap + self.Object = doc.getObject(state['ObjectName']) + + def claimChildren(self): + objs = [] + if hasattr(self.Object, "baseObject"): + objs.append(self.Object.baseObject[0]) + return objs + + def getIcon(self): + return os.path.join(icons_path, 'SheetMetal_AddRelief.svg') + + def setEdit(self, vobj, mode): + taskd = SMReliefTaskPanel() + taskd.obj = vobj.Object + taskd.update() + self.Object.ViewObject.Visibility = False + self.Object.baseObject[0].ViewObject.Visibility = True + Gui.Control.showDialog(taskd) + return True + + def unsetEdit(self, vobj, mode): + Gui.Control.closeDialog() + self.Object.baseObject[0].ViewObject.Visibility = False + self.Object.ViewObject.Visibility = True + return False + class SMReliefViewProviderFlat: - "A View provider that nests children objects under the created one" - - def __init__(self, obj): - obj.Proxy = self - self.Object = obj.Object - - def attach(self, obj): - self.Object = obj.Object - return - - def updateData(self, fp, prop): - return - - def getDisplayModes(self,obj): - modes=[] - return modes - - def setDisplayMode(self,mode): - return mode - - def onChanged(self, vp, prop): - return - - def __getstate__(self): - # return {'ObjectName' : self.Object.Name} - return None - - def __setstate__(self, state): - self.loads(state) - - # dumps and loads replace __getstate__ and __setstate__ post v. 0.21.2 - def dumps(self): - return None - - def loads(self, state): - if state is not None: - import FreeCAD - doc = FreeCAD.ActiveDocument #crap - self.Object = doc.getObject(state['ObjectName']) - - def claimChildren(self): - - return [] - - def getIcon(self): - return os.path.join( icons_path , 'SheetMetal_AddRelief.svg') - - def setEdit(self,vobj,mode): - taskd = SMReliefTaskPanel() - taskd.obj = vobj.Object - taskd.update() - self.Object.ViewObject.Visibility=False - self.Object.baseObject[0].ViewObject.Visibility=True - Gui.Control.showDialog(taskd) - return True - - def unsetEdit(self,vobj,mode): - Gui.Control.closeDialog() - self.Object.baseObject[0].ViewObject.Visibility=False - self.Object.ViewObject.Visibility=True - return False - + "A View provider that nests children objects under the created one" + + def __init__(self, obj): + obj.Proxy = self + self.Object = obj.Object + + def attach(self, obj): + self.Object = obj.Object + return + + def updateData(self, fp, prop): + return + + def getDisplayModes(self, obj): + modes = [] + return modes + + def setDisplayMode(self, mode): + return mode + + def onChanged(self, vp, prop): + return + + def __getstate__(self): + # return {'ObjectName' : self.Object.Name} + return None + + def __setstate__(self, state): + self.loads(state) + + # dumps and loads replace __getstate__ and __setstate__ post v. 0.21.2 + def dumps(self): + return None + + def loads(self, state): + if state is not None: + import FreeCAD + doc = FreeCAD.ActiveDocument # crap + self.Object = doc.getObject(state['ObjectName']) + + def claimChildren(self): + + return [] + + def getIcon(self): + return os.path.join(icons_path, 'SheetMetal_AddRelief.svg') + + def setEdit(self, vobj, mode): + taskd = SMReliefTaskPanel() + taskd.obj = vobj.Object + taskd.update() + self.Object.ViewObject.Visibility = False + self.Object.baseObject[0].ViewObject.Visibility = True + Gui.Control.showDialog(taskd) + return True + + def unsetEdit(self, vobj, mode): + Gui.Control.closeDialog() + self.Object.baseObject[0].ViewObject.Visibility = False + self.Object.ViewObject.Visibility = True + return False + class SMReliefTaskPanel: '''A TaskPanel for the Sheetmetal''' + def __init__(self): - - self.obj = None - self.form = QtGui.QWidget() - self.form.setObjectName("SMReliefTaskPanel") - self.form.setWindowTitle("Binded vertexes list") - 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) - self.title.setText("Select new vertex(es) and press Update") - - # tree - self.tree = QtGui.QTreeWidget(self.form) - self.grid.addWidget(self.tree, 1, 0, 1, 2) - self.tree.setColumnCount(2) - self.tree.setHeaderLabels(["Name","Subelement"]) - - # buttons - self.addButton = QtGui.QPushButton(self.form) - self.addButton.setObjectName("addButton") - self.addButton.setIcon(QtGui.QIcon(os.path.join( icons_path , 'SheetMetal_Update.svg'))) - self.grid.addWidget(self.addButton, 3, 0, 1, 2) - - QtCore.QObject.connect(self.addButton, QtCore.SIGNAL("clicked()"), self.updateElement) - self.update() - + + self.obj = None + self.form = QtGui.QWidget() + self.form.setObjectName("SMReliefTaskPanel") + self.form.setWindowTitle("Binded vertexes list") + 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) + self.title.setText("Select new vertex(es) and press Update") + + # tree + self.tree = QtGui.QTreeWidget(self.form) + self.grid.addWidget(self.tree, 1, 0, 1, 2) + self.tree.setColumnCount(2) + self.tree.setHeaderLabels(["Name", "Subelement"]) + + # buttons + self.addButton = QtGui.QPushButton(self.form) + self.addButton.setObjectName("addButton") + self.addButton.setIcon(QtGui.QIcon( + os.path.join(icons_path, 'SheetMetal_Update.svg'))) + self.grid.addWidget(self.addButton, 3, 0, 1, 2) + + QtCore.QObject.connect(self.addButton, QtCore.SIGNAL( + "clicked()"), self.updateElement) + self.update() + def isAllowedAlterSelection(self): return True - + def isAllowedAlterView(self): return True - + def getStandardButtons(self): return QtGui.QDialogButtonBox.Ok - + def update(self): - 'fills the treewidget' - self.tree.clear() - if self.obj: - f = self.obj.baseObject - if isinstance(f[1],list): - for subf in f[1]: - #FreeCAD.Console.PrintLog("item: " + subf + "\n") - item = QtGui.QTreeWidgetItem(self.tree) - item.setText(0,f[0].Name) - item.setIcon(0,QtGui.QIcon(":/icons/Tree_Part.svg")) - item.setText(1,subf) - else: - item = QtGui.QTreeWidgetItem(self.tree) - item.setText(0,f[0].Name) - item.setIcon(0,QtGui.QIcon(":/icons/Tree_Part.svg")) - item.setText(1,f[1][0]) - self.retranslateUi(self.form) - + 'fills the treewidget' + self.tree.clear() + if self.obj: + f = self.obj.baseObject + if isinstance(f[1], list): + for subf in f[1]: + # FreeCAD.Console.PrintLog("item: " + subf + "\n") + item = QtGui.QTreeWidgetItem(self.tree) + item.setText(0, f[0].Name) + item.setIcon(0, QtGui.QIcon(":/icons/Tree_Part.svg")) + item.setText(1, subf) + else: + item = QtGui.QTreeWidgetItem(self.tree) + item.setText(0, f[0].Name) + item.setIcon(0, QtGui.QIcon(":/icons/Tree_Part.svg")) + item.setText(1, f[1][0]) + self.retranslateUi(self.form) + def updateElement(self): - if self.obj: - sel = Gui.Selection.getSelectionEx()[0] - if sel.HasSubObjects: - obj = sel.Object - for elt in sel.SubElementNames: - if "Vertex" in elt: - vertex = self.obj.baseObject - found = False - if (vertex[0] == obj.Name): - if isinstance(vertex[1],tuple): - for subf in vertex[1]: - if subf == elt: - found = True - else: - if (vertex[1][0] == elt): - found = True - if not found: - self.obj.baseObject = (sel.Object, sel.SubElementNames) - self.update() - + if self.obj: + sel = Gui.Selection.getSelectionEx()[0] + if sel.HasSubObjects: + obj = sel.Object + for elt in sel.SubElementNames: + if "Vertex" in elt: + vertex = self.obj.baseObject + found = False + if (vertex[0] == obj.Name): + if isinstance(vertex[1], tuple): + for subf in vertex[1]: + if subf == elt: + found = True + else: + if (vertex[1][0] == elt): + found = True + if not found: + self.obj.baseObject = ( + sel.Object, sel.SubElementNames) + self.update() + def accept(self): FreeCAD.ActiveDocument.recompute() Gui.ActiveDocument.resetEdit() - #self.obj.ViewObject.Visibility=True + # self.obj.ViewObject.Visibility=True return True def retranslateUi(self, TaskPanel): - #TaskPanel.setWindowTitle(QtGui.QApplication.translate("draft", "vertexs", None)) - self.addButton.setText(QtGui.QApplication.translate("draft", "Update", None)) - + # TaskPanel.setWindowTitle(QtGui.QApplication.translate("draft", "vertexs", None)) + self.addButton.setText( + QtGui.QApplication.translate("draft", "Update", None)) class AddReliefCommandClass(): - """Add Relief command""" - - def GetResources(self): - return {'Pixmap' : os.path.join( icons_path , 'SheetMetal_AddRelief.svg'), # the name of a svg file available in the resources - 'MenuText': FreeCAD.Qt.translate('SheetMetal','Make Relief'), - 'Accel': "S, R", - 'ToolTip' : FreeCAD.Qt.translate('SheetMetal','Modify an Individual solid corner to create Relief.\n' - '1. Select Vertex(es) to create Relief on Solid corner Vertex(es).\n' - '2. Use Property editor to modify default parameters')} - - def Activated(self): - doc = FreeCAD.ActiveDocument - view = Gui.ActiveDocument.ActiveView - activeBody = None - sel = Gui.Selection.getSelectionEx()[0] - selobj = Gui.Selection.getSelectionEx()[0].Object - viewConf = SheetMetalTools.GetViewConfig(selobj) - if hasattr(view,'getActiveObject'): - activeBody = view.getActiveObject('pdbody') - if not SheetMetalTools.smIsOperationLegal(activeBody, selobj): + """Add Relief command""" + + def GetResources(self): + return {'Pixmap': os.path.join(icons_path, 'SheetMetal_AddRelief.svg'), # the name of a svg file available in the resources + 'MenuText': FreeCAD.Qt.translate('SheetMetal', 'Make Relief'), + 'Accel': "S, R", + 'ToolTip': FreeCAD.Qt.translate('SheetMetal', 'Modify an Individual solid corner to create Relief.\n' + '1. Select Vertex(es) to create Relief on Solid corner Vertex(es).\n' + '2. Use Property editor to modify default parameters')} + + def Activated(self): + doc = FreeCAD.ActiveDocument + view = Gui.ActiveDocument.ActiveView + activeBody = None + sel = Gui.Selection.getSelectionEx()[0] + selobj = Gui.Selection.getSelectionEx()[0].Object + viewConf = SheetMetalTools.GetViewConfig(selobj) + if hasattr(view, 'getActiveObject'): + activeBody = view.getActiveObject('pdbody') + if not SheetMetalTools.smIsOperationLegal(activeBody, selobj): + return + doc.openTransaction("Add Relief") + if activeBody is None or not SheetMetalTools.smIsPartDesign(selobj): + a = doc.addObject("Part::FeaturePython", "Relief") + SMRelief(a) + a.baseObject = (selobj, sel.SubElementNames) + SMReliefViewProviderTree(a.ViewObject) + else: + # FreeCAD.Console.PrintLog("found active body: " + activeBody.Name) + a = doc.addObject("PartDesign::FeaturePython", "Relief") + SMRelief(a) + a.baseObject = (selobj, sel.SubElementNames) + SMReliefViewProviderFlat(a.ViewObject) + activeBody.addObject(a) + SheetMetalTools.SetViewConfig(a, viewConf) + Gui.Selection.clearSelection() + doc.recompute() + doc.commitTransaction() return - doc.openTransaction("Add Relief") - if activeBody is None or not SheetMetalTools.smIsPartDesign(selobj): - a = doc.addObject("Part::FeaturePython","Relief") - SMRelief(a) - a.baseObject = (selobj, sel.SubElementNames) - SMReliefViewProviderTree(a.ViewObject) - else: - #FreeCAD.Console.PrintLog("found active body: " + activeBody.Name) - a = doc.addObject("PartDesign::FeaturePython","Relief") - SMRelief(a) - a.baseObject = (selobj, sel.SubElementNames) - SMReliefViewProviderFlat(a.ViewObject) - activeBody.addObject(a) - SheetMetalTools.SetViewConfig(a, viewConf) - Gui.Selection.clearSelection() - doc.recompute() - doc.commitTransaction() - return - - def IsActive(self): - if len(Gui.Selection.getSelection()) < 1 or len(Gui.Selection.getSelectionEx()[0].SubElementNames) < 1: - return False + + def IsActive(self): + if len(Gui.Selection.getSelection()) < 1 or len(Gui.Selection.getSelectionEx()[0].SubElementNames) < 1: + return False # selobj = Gui.Selection.getSelection()[0] - for selVertex in Gui.Selection.getSelectionEx()[0].SubObjects: - if type(selVertex) != Part.Vertex : - return False - return True + for selVertex in Gui.Selection.getSelectionEx()[0].SubObjects: + if type(selVertex) != Part.Vertex: + return False + return True Gui.addCommand("SheetMetal_AddRelief", AddReliefCommandClass()) diff --git a/SheetMetalTools.py b/SheetMetalTools.py index 3dbd2b1..49727c0 100644 --- a/SheetMetalTools.py +++ b/SheetMetalTools.py @@ -62,12 +62,15 @@ def taskPopulateSelectionList(qwidget, baseObject): item.setText(1, subf) def taskPopulateSelectionSingle(textbox, baseObject): - if isinstance(baseObject, tuple): + if baseObject is None: + textbox.setText("") + elif isinstance(baseObject, tuple): obj, items = baseObject item = "None" if len(items) == 0 else items[0] textbox.setText(f"{obj.Name}: {item}") else: textbox.setText(baseObject.Name) + def updateSelectionElements(obj, allowedTypes): if not obj: return