Added boundary dressup to restrict path to another shape.
This commit is contained in:
@@ -88,6 +88,7 @@
|
||||
<file>panels/DlgToolEdit.ui</file>
|
||||
<file>panels/DlgTCChooser.ui</file>
|
||||
<file>panels/DogboneEdit.ui</file>
|
||||
<file>panels/DressupPathBoundary.ui</file>
|
||||
<file>panels/HoldingTagsEdit.ui</file>
|
||||
<file>panels/PageBaseGeometryEdit.ui</file>
|
||||
<file>panels/PageBaseHoleGeometryEdit.ui</file>
|
||||
|
||||
238
src/Mod/Path/Gui/Resources/panels/DressupPathBoundary.ui
Normal file
238
src/Mod/Path/Gui/Resources/panels/DressupPathBoundary.ui
Normal file
@@ -0,0 +1,238 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form</class>
|
||||
<widget class="QWidget" name="Form">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>263</width>
|
||||
<height>508</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="boundaryGroup">
|
||||
<property name="title">
|
||||
<string>Boundary Body</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWidget" name="widget_2" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QComboBox" name="boundary">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Create Box</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Create Cylinder</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Extend Model's Bound Box</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Use Existing Solid</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>6</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="boundaryFromExisting">
|
||||
<layout class="QGridLayout" name="gridLayout_8">
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="boundaryExisting"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="boundaryFromBase">
|
||||
<layout class="QGridLayout" name="gridLayout_9">
|
||||
<item row="1" column="3">
|
||||
<widget class="Gui::InputField" name="boundaryExtYpos"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="boundaryExtXLabel">
|
||||
<property name="text">
|
||||
<string>Ext. X</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="Gui::InputField" name="boundaryExtXpos">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="boundaryExtYLabel">
|
||||
<property name="text">
|
||||
<string>Ext. Y</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="Gui::InputField" name="boundaryExtXneg"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="boundaryExtZLabel">
|
||||
<property name="text">
|
||||
<string>Ext. Z</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="Gui::InputField" name="boundaryExtZneg"/>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="Gui::InputField" name="boundaryExtZpos"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="Gui::InputField" name="boundaryExtYneg"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="boundaryCreateCylinder">
|
||||
<layout class="QGridLayout" name="gridLayout_10">
|
||||
<item row="0" column="2">
|
||||
<widget class="Gui::InputField" name="boundaryCylinderRadius"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="Gui::InputField" name="boundaryCylinderHeight"/>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="boundaryCylinderRadiusLabel">
|
||||
<property name="text">
|
||||
<string>Radius</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="boundaryCylinderHeightLabel">
|
||||
<property name="text">
|
||||
<string>Height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QFrame" name="boundaryCreateBox">
|
||||
<layout class="QGridLayout" name="gridLayout_11">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="boundaryBoxLengthLabel">
|
||||
<property name="text">
|
||||
<string>Length</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="boundaryBoxWidthLabel">
|
||||
<property name="text">
|
||||
<string>Width</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="Gui::InputField" name="boundaryBoxLength"/>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="Gui::InputField" name="boundaryBoxHeight"/>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="Gui::InputField" name="boundaryBoxWidth"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLabel" name="boundaryBoxHeightLabel">
|
||||
<property name="text">
|
||||
<string>Height</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="boundaryInside">
|
||||
<property name="text">
|
||||
<string>Constrained to Inside</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Gui::InputField</class>
|
||||
<extends>QLineEdit</extends>
|
||||
<header>Gui/InputField.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -82,7 +82,7 @@ class PathWorkbench (Workbench):
|
||||
threedopcmdlist = ["Path_Pocket_3D"]
|
||||
engravecmdlist = ["Path_Engrave", "Path_Deburr"]
|
||||
modcmdlist = ["Path_OperationCopy", "Path_Array", "Path_SimpleCopy" ]
|
||||
dressupcmdlist = ["Path_DressupAxisMap", "Path_DressupDogbone", "Path_DressupDragKnife", "Path_DressupLeadInOut", "Path_DressupRampEntry", "Path_DressupTag"]
|
||||
dressupcmdlist = ["Path_DressupAxisMap", "Path_DressupPathBoundary", "Path_DressupDogbone", "Path_DressupDragKnife", "Path_DressupLeadInOut", "Path_DressupRampEntry", "Path_DressupTag"]
|
||||
extracmdlist = []
|
||||
#modcmdmore = ["Path_Hop",]
|
||||
#remotecmdlist = ["Path_Remote"]
|
||||
|
||||
192
src/Mod/Path/PathScripts/PathDressupPathBoundary.py
Normal file
192
src/Mod/Path/PathScripts/PathDressupPathBoundary.py
Normal file
@@ -0,0 +1,192 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2019 sliptonic <shopinthewoods@gmail.com> *
|
||||
# * *
|
||||
# * 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 Path
|
||||
import PathScripts.PathGeom as PathGeom
|
||||
import PathScripts.PathLog as PathLog
|
||||
import PathScripts.PathStock as PathStock
|
||||
import PathScripts.PathUtil as PathUtil
|
||||
import PathScripts.PathUtils as PathUtils
|
||||
|
||||
from PySide import QtCore
|
||||
|
||||
PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
|
||||
PathLog.trackModule(PathLog.thisModule())
|
||||
|
||||
def _vstr(v):
|
||||
if v:
|
||||
return "(%.2f, %.2f, %.2f)" % (v.x, v.y, v.z)
|
||||
return '-'
|
||||
|
||||
class DressupPathBoundary(object):
|
||||
|
||||
def __init__(self, obj, base, job):
|
||||
obj.addProperty("App::PropertyLink", "Base", "Base", QtCore.QT_TRANSLATE_NOOP("Path_DressupPathBoundary", "The base path to modify"))
|
||||
obj.Base = base
|
||||
obj.addProperty("App::PropertyLink", "Boundary", "Boundary", QtCore.QT_TRANSLATE_NOOP("Path_DressupPathBoundary", "Solid object to be used to limit the generated Path."))
|
||||
obj.Boundary = PathStock.CreateFromBase(job)
|
||||
obj.addProperty("App::PropertyBool", "Inside", "Boundary", QtCore.QT_TRANSLATE_NOOP("Path_DressupPathBoundary", "Determines if Boundary describes an inclusion or exclusion mask."))
|
||||
obj.Inside = True
|
||||
|
||||
self.obj = obj
|
||||
self.safeHeight = None
|
||||
self.clearanceHeight = None
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
def __setstate__(self, state):
|
||||
return None
|
||||
|
||||
def onDcoumentRestored(self, obj):
|
||||
self.obj = obj
|
||||
|
||||
def onDelete(self, obj, args):
|
||||
if obj.Boundary:
|
||||
obj.Document.removeObject(obj.Boundary.Name)
|
||||
obj.Boundary = None
|
||||
|
||||
def boundaryCommands(self, obj, begin, end):
|
||||
PathLog.track(_vstr(begin), _vstr(end))
|
||||
if end and PathGeom.pointsCoincide(begin, end):
|
||||
return []
|
||||
cmds = []
|
||||
if begin.z < self.safeHeight:
|
||||
cmds.append(Path.Command('G1', {'Z': self.safeHeight}))
|
||||
if begin.z < self.clearanceHeight:
|
||||
cmds.append(Path.Command('G0', {'Z': self.clearanceHeight}))
|
||||
if end:
|
||||
cmds.append(Path.Command('G0', {'X': end.x, 'Y': end.y}))
|
||||
if end.z < self.clearanceHeight:
|
||||
cmds.append(Path.Command('G0', {'Z': max(self.safeHeight, end.z)}))
|
||||
if end.z < self.safeHeight:
|
||||
cmds.append(Path.Command('G1', {'Z': end.z}))
|
||||
return cmds
|
||||
|
||||
def execute(self, obj):
|
||||
if not obj.Base or not obj.Base.isDerivedFrom('Path::Feature') or not obj.Base.Path:
|
||||
return
|
||||
|
||||
if len(obj.Base.Path.Commands) > 0:
|
||||
self.safeHeight = float(PathUtil.opProperty(obj.Base, 'SafeHeight'))
|
||||
self.clearanceHeight = float(PathUtil.opProperty(obj.Base, 'ClearanceHeight'))
|
||||
|
||||
boundary = obj.Boundary.Shape
|
||||
cmd = obj.Base.Path.Commands[0]
|
||||
pos = cmd.Placement.Base
|
||||
commands = [cmd]
|
||||
lastExit = None
|
||||
for cmd in obj.Base.Path.Commands[1:]:
|
||||
if cmd.Name in PathGeom.CmdMoveAll:
|
||||
edge = PathGeom.edgeForCmd(cmd, pos)
|
||||
inside = edge.common(boundary).Edges
|
||||
outside = edge.cut(boundary).Edges
|
||||
if not obj.Inside:
|
||||
t = inside
|
||||
inside = outside
|
||||
outside = t
|
||||
# it's really a shame that one cannot trust the sequence and/or
|
||||
# orientation of edges
|
||||
if 1 == len(inside) and 0 == len(outside):
|
||||
PathLog.track(_vstr(pos), _vstr(lastExit), ' + ', cmd)
|
||||
# cmd fully included by boundary
|
||||
if lastExit:
|
||||
commands.extend(self.boundaryCommands(obj, lastExit, pos))
|
||||
lastExit = None
|
||||
commands.append(cmd)
|
||||
pos = PathGeom.commandEndPoint(cmd, pos)
|
||||
elif 0 == len(inside) and 1 == len(outside):
|
||||
PathLog.track(_vstr(pos), _vstr(lastExit), ' - ', cmd)
|
||||
# cmd fully excluded by boundary
|
||||
if not lastExit:
|
||||
lastExit = pos
|
||||
pos = PathGeom.commandEndPoint(cmd, pos)
|
||||
else:
|
||||
PathLog.track(_vstr(pos), _vstr(lastExit), len(inside), len(outside), cmd)
|
||||
# cmd pierces Boundary
|
||||
while inside or outside:
|
||||
ie = [e for e in inside if PathGeom.edgeConnectsTo(e, pos)]
|
||||
PathLog.track(ie)
|
||||
if ie:
|
||||
e = ie[0]
|
||||
ptL = e.valueAt(e.LastParameter)
|
||||
flip = PathGeom.pointsCoincide(pos, ptL)
|
||||
newPos = e.valueAt(e.FirstParameter) if flip else ptL
|
||||
# inside edges are taken at this point (see swap of inside/outside
|
||||
# above - so we can just connect the dots ...
|
||||
if lastExit:
|
||||
commands.extend(self.boundaryCommands(obj, lastExit, pos))
|
||||
lastExit = None
|
||||
PathLog.track(e, flip)
|
||||
commands.extend(PathGeom.cmdsForEdge(e, flip, False))
|
||||
inside.remove(e)
|
||||
pos = newPos
|
||||
lastExit = newPos
|
||||
else:
|
||||
oe = [e for e in outside if PathGeom.edgeConnectsTo(e, pos)]
|
||||
PathLog.track(oe)
|
||||
if oe:
|
||||
e = oe[0]
|
||||
ptL = e.valueAt(e.LastParameter)
|
||||
flip = PathGeom.pointsCoincide(pos, ptL)
|
||||
newPos = e.valueAt(e.FirstParameter) if flip else ptL
|
||||
# outside edges are never taken at this point (see swap of
|
||||
# inside/oustide above) - so just move along ...
|
||||
outside.remove(e)
|
||||
pos = newPos
|
||||
else:
|
||||
PathLog.error('huh?')
|
||||
import Part
|
||||
Part.show(Part.Vertex(pos), 'pos')
|
||||
for e in inside:
|
||||
Part.show(e, 'ei')
|
||||
for e in outside:
|
||||
Part.show(e, 'eo')
|
||||
raise Exception('This is not supposed to happen')
|
||||
#pos = PathGeom.commandEndPoint(cmd, pos)
|
||||
else:
|
||||
PathLog.track('no-move', cmd)
|
||||
commands.append(cmd)
|
||||
if lastExit:
|
||||
commands.extend(self.boundaryCommands(obj, lastExit, None))
|
||||
lastExit = None
|
||||
else:
|
||||
PathLog.warning("No Path Commands for %s" % obj.Base.Label)
|
||||
commands = []
|
||||
PathLog.track(commands)
|
||||
obj.Path = Path.Path(commands)
|
||||
|
||||
|
||||
def Create(base, name='DressupPathBoundary'):
|
||||
'''Create(base, name='DressupPathBoundary') ... creates a dressup limiting base's Path to a boundary.'''
|
||||
|
||||
if not base.isDerivedFrom('Path::Feature'):
|
||||
PathLog.error(translate('Path_DressupPathBoundary', 'The selected object is not a path')+'\n')
|
||||
return None
|
||||
|
||||
obj = FreeCAD.ActiveDocument.addObject('Path::FeaturePython', name)
|
||||
job = PathUtils.findParentJob(base)
|
||||
obj.Proxy = DressupPathBoundary(obj, base, job)
|
||||
job.Proxy.addOperation(obj, base)
|
||||
return obj
|
||||
169
src/Mod/Path/PathScripts/PathDressupPathBoundaryGui.py
Normal file
169
src/Mod/Path/PathScripts/PathDressupPathBoundaryGui.py
Normal file
@@ -0,0 +1,169 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2019 sliptonic <shopinthewoods@gmail.com> *
|
||||
# * *
|
||||
# * 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 FreeCADGui
|
||||
import PathScripts.PathDressupPathBoundary as PathDressupPathBoundary
|
||||
import PathScripts.PathLog as PathLog
|
||||
|
||||
from PySide import QtGui, QtCore
|
||||
|
||||
PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
|
||||
# PathLog.trackModule()
|
||||
|
||||
|
||||
# Qt translation handling
|
||||
def translate(context, text, disambig=None):
|
||||
return QtCore.QCoreApplication.translate(context, text, disambig)
|
||||
|
||||
class TaskPanel(object):
|
||||
|
||||
def __init__(self, obj, viewProvider):
|
||||
self.obj = obj
|
||||
self.viewProvider = viewProvider
|
||||
self.form = FreeCADGui.PySideUic.loadUi(':/panels/DressupPathBoundary.ui')
|
||||
self.visibilityBase = obj.Base.ViewObject.Visibility if obj.Base else None
|
||||
self.visibilityBoundary = obj.Boundary.ViewObject.Visibility if obj.Boundary else None
|
||||
|
||||
def getStandardButtons(self):
|
||||
return int(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Apply | QtGui.QDialogButtonBox.Cancel)
|
||||
|
||||
def abort(self):
|
||||
FreeCAD.ActiveDocument.abortTransaction()
|
||||
self.cleanup(False)
|
||||
|
||||
def reject(self):
|
||||
FreeCAD.ActiveDocument.abortTransaction()
|
||||
self.cleanup(True)
|
||||
|
||||
def accept(self):
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
self.cleanup(True)
|
||||
#if self.isDirty:
|
||||
# self.getFields()
|
||||
# FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
def cleanup(self, gui):
|
||||
self.viewProvider.clearTaskPanel()
|
||||
if gui:
|
||||
FreeCADGui.ActiveDocument.resetEdit()
|
||||
FreeCADGui.Control.closeDialog()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
if self.obj.Base:
|
||||
self.obj.Base.ViewObject.Visibility = self.visibilityBase
|
||||
if self.obj.Boundary:
|
||||
self.obj.Boundary.ViewObject.Visibility = self.visibilityBoundary
|
||||
|
||||
def getFields(self):
|
||||
pass
|
||||
def setFields(self):
|
||||
pass
|
||||
|
||||
def setupUi(self):
|
||||
pass
|
||||
|
||||
|
||||
class DressupPathBoundaryViewProvider(object):
|
||||
|
||||
def __init__(self, vobj):
|
||||
self.attach(vobj)
|
||||
|
||||
def __getstate__(self):
|
||||
return None
|
||||
def __setstate_(self, state):
|
||||
return None
|
||||
|
||||
|
||||
def attach(self, vobj):
|
||||
self.vobj = vobj
|
||||
self.obj = vobj.Object
|
||||
self.panel = None
|
||||
|
||||
def claimChildren(self):
|
||||
return [self.obj.Base, self.obj.Boundary]
|
||||
|
||||
def onDelete(self, vobj, args=None):
|
||||
vobj.Object.Proxy.onDelete(vobj.Object, args)
|
||||
|
||||
def setEdit(self, vobj, mode=0):
|
||||
panel = TaskPanel(vobj.Object, self)
|
||||
self.setupTaskPanel(panel)
|
||||
return True
|
||||
|
||||
def unsetEdit(self, vobj, mode=0):
|
||||
if self.panel:
|
||||
self.panel.abort()
|
||||
|
||||
def setupTaskPanel(self, panel):
|
||||
self.panel = panel
|
||||
FreeCADGui.Control.closeDialog()
|
||||
FreeCADGui.Control.showDialog(panel)
|
||||
panel.setupUi()
|
||||
|
||||
def clearTaskPanel(self):
|
||||
self.panel = None
|
||||
|
||||
|
||||
def Create(base, name='DressupPathBoundary'):
|
||||
FreeCAD.ActiveDocument.openTransaction(translate('Path_DressupPathBoundary', 'Create a Boundary dressup'))
|
||||
obj = PathDressupPathBoundary.Create(base, name)
|
||||
obj.ViewObject.Proxy = DressupPathBoundaryViewProvider(obj.ViewObject)
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
obj.ViewObject.Document.setEdit(obj.ViewObject, 0)
|
||||
return obj
|
||||
|
||||
class CommandPathDressupPathBoundary:
|
||||
# pylint: disable=no-init
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'Path-Dressup',
|
||||
'MenuText': QtCore.QT_TRANSLATE_NOOP('Path_DressupPathBoundary', 'Boundary Dress-up'),
|
||||
'ToolTip': QtCore.QT_TRANSLATE_NOOP('Path_DressupPathBoundary', 'Creates a Path Boundary Dress-up object from a selected path')}
|
||||
|
||||
def IsActive(self):
|
||||
if FreeCAD.ActiveDocument is not None:
|
||||
for o in FreeCAD.ActiveDocument.Objects:
|
||||
if o.Name[:3] == 'Job':
|
||||
return True
|
||||
return False
|
||||
|
||||
def Activated(self):
|
||||
# check that the selection contains exactly what we want
|
||||
selection = FreeCADGui.Selection.getSelection()
|
||||
if len(selection) != 1:
|
||||
PathLog.error(translate('Path_DressupPathBoundary', 'Please select one path object')+'\n')
|
||||
return
|
||||
baseObject = selection[0]
|
||||
|
||||
# everything ok!
|
||||
FreeCAD.ActiveDocument.openTransaction(translate('Path_DressupPathBoundary', 'Create Path Boundary Dress-up'))
|
||||
FreeCADGui.addModule('PathScripts.PathDressupPathBoundaryGui')
|
||||
FreeCADGui.doCommand("PathScripts.PathDressupPathBoundaryGui.Create(App.ActiveDocument.%s)" % baseObject.Name)
|
||||
FreeCAD.ActiveDocument.commitTransaction()
|
||||
FreeCAD.ActiveDocument.recompute()
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
# register the FreeCAD command
|
||||
FreeCADGui.addCommand('Path_DressupPathBoundary', CommandPathDressupPathBoundary())
|
||||
|
||||
PathLog.notice('Loading PathDressupPathBoundaryGui... done\n')
|
||||
@@ -87,6 +87,7 @@ CmdMoveCW = ['G2', 'G02']
|
||||
CmdMoveCCW = ['G3', 'G03']
|
||||
CmdMoveArc = CmdMoveCW + CmdMoveCCW
|
||||
CmdMove = CmdMoveStraight + CmdMoveArc
|
||||
CmdMoveAll = CmdMove + CmdMoveRapid
|
||||
|
||||
def isRoughly(float1, float2, error=Tolerance):
|
||||
"""isRoughly(float1, float2, [error=Tolerance])
|
||||
|
||||
@@ -48,6 +48,7 @@ def Startup():
|
||||
from PathScripts import PathDressupDogbone
|
||||
from PathScripts import PathDressupDragknife
|
||||
from PathScripts import PathDressupRampEntry
|
||||
from PathScripts import PathDressupPathBoundaryGui
|
||||
from PathScripts import PathDressupTagGui
|
||||
from PathScripts import PathDressupLeadInOut
|
||||
from PathScripts import PathDrillingGui
|
||||
|
||||
@@ -68,15 +68,19 @@ def isSolid(obj):
|
||||
shape = Part.getShape(obj)
|
||||
return not shape.isNull() and shape.Volume and shape.isClosed()
|
||||
|
||||
def opProperty(op, prop):
|
||||
'''opProperty(op, prop) ... return the value of property prop of the underlying operation (or None if prop does not exist)'''
|
||||
if hasattr(op, prop):
|
||||
return getattr(op, prop)
|
||||
if hasattr(op, 'Base'):
|
||||
return opProperty(op.Base, prop)
|
||||
return None
|
||||
|
||||
def toolControllerForOp(op):
|
||||
'''toolControllerForOp(op) ... return the tool controller used by the op.
|
||||
If the op doesn't have its own tool controller but has a Base object, return its tool controller.
|
||||
Otherwise return None.'''
|
||||
if hasattr(op, 'ToolController'):
|
||||
return op.ToolController
|
||||
if hasattr(op, 'Base'):
|
||||
return toolControllerForOp(op.Base)
|
||||
return None
|
||||
return opProperty(op, 'ToolController')
|
||||
|
||||
def getPublicObject(obj):
|
||||
'''getPublicObject(obj) ... returns the object which should be used to reference a feature of the given object.'''
|
||||
|
||||
Reference in New Issue
Block a user