diff --git a/src/Mod/Path/CMakeLists.txt b/src/Mod/Path/CMakeLists.txt
index cd3c112546..d6df197041 100644
--- a/src/Mod/Path/CMakeLists.txt
+++ b/src/Mod/Path/CMakeLists.txt
@@ -57,6 +57,7 @@ SET(PathScripts_SRCS
PathScripts/PathPreferencesPathDressup.py
PathScripts/PathPreferencesPathJob.py
PathScripts/PathProfile.py
+ PathScripts/PathProfileGui.py
PathScripts/PathProfileEdges.py
PathScripts/PathSanity.py
PathScripts/PathSelection.py
diff --git a/src/Mod/Path/Gui/Resources/Path.qrc b/src/Mod/Path/Gui/Resources/Path.qrc
index b192c40a6d..148d3e7a77 100644
--- a/src/Mod/Path/Gui/Resources/Path.qrc
+++ b/src/Mod/Path/Gui/Resources/Path.qrc
@@ -66,6 +66,7 @@
panels/PageHeightsEdit.ui
panels/PageOpContourEdit.ui
panels/PageOpPocketEdit.ui
+ panels/PageOpProfileEdit.ui
panels/PocketEdit.ui
panels/PointEdit.ui
panels/ProfileEdgesEdit.ui
diff --git a/src/Mod/Path/Gui/Resources/panels/PageOpProfileEdit.ui b/src/Mod/Path/Gui/Resources/panels/PageOpProfileEdit.ui
new file mode 100644
index 0000000000..44f8fa3791
--- /dev/null
+++ b/src/Mod/Path/Gui/Resources/panels/PageOpProfileEdit.ui
@@ -0,0 +1,169 @@
+
+
+ Form
+
+
+
+ 0
+ 0
+ 446
+ 419
+
+
+
+ Form
+
+
+ -
+
+
+ QFrame::StyledPanel
+
+
+ QFrame::Raised
+
+
+
-
+
+
+ Tool Controller
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
-
+
+
+ Cut Side
+
+
+
+ -
+
+
-
+
+ Outside
+
+
+ -
+
+ Inside
+
+
+
+
+ -
+
+
+ Direction
+
+
+
+ -
+
+
-
+
+ CW
+
+
+ -
+
+ CCW
+
+
+
+
+ -
+
+
+ Extra Offset
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+
+
+
+ -
+
+
+
-
+
+
+ Use Start Point
+
+
+
+ -
+
+
+ Process Holes
+
+
+
+ -
+
+
+ Use Compensation
+
+
+
+ -
+
+
+ Process Cirles
+
+
+
+ -
+
+
+ Process Perimeter
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ Gui::InputField
+ QLineEdit
+
+
+
+
+
+
diff --git a/src/Mod/Path/InitGui.py b/src/Mod/Path/InitGui.py
index be13d90c3f..2ea2bffebc 100644
--- a/src/Mod/Path/InitGui.py
+++ b/src/Mod/Path/InitGui.py
@@ -67,7 +67,7 @@ class PathWorkbench (Workbench):
from PathScripts import PathPlane
from PathScripts import PathPocketGui
from PathScripts import PathPost
- from PathScripts import PathProfile
+ from PathScripts import PathProfileGui
from PathScripts import PathProfileEdges
from PathScripts import PathSanity
from PathScripts import PathSimpleCopy
diff --git a/src/Mod/Path/PathScripts/PathAreaOp.py b/src/Mod/Path/PathScripts/PathAreaOp.py
index 640c814338..a0f0df1ae6 100644
--- a/src/Mod/Path/PathScripts/PathAreaOp.py
+++ b/src/Mod/Path/PathScripts/PathAreaOp.py
@@ -44,15 +44,16 @@ PathLog.trackModule()
def translate(context, text, disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
-FeatureTool = 0x01
-FeatureDepths = 0x02
-FeatureHeights = 0x04
-FeatureStartPoint = 0x08
-FeatureBaseFaces = 0x10
-FeatureBaseEdges = 0x20
-FeatureFinishDepth = 0x40
+FeatureTool = 0x0001
+FeatureDepths = 0x0002
+FeatureHeights = 0x0004
+FeatureStartPoint = 0x0008
+FeatureFinishDepth = 0x0010
+FeatureBaseFaces = 0x1001
+FeatureBaseEdges = 0x1002
+FeatureBasePanels = 0x1002
-FeatureBaseGeometry = FeatureBaseFaces | FeatureBaseEdges
+FeatureBaseGeometry = FeatureBaseFaces | FeatureBaseEdges | FeatureBasePanels
class ObjectOp(object):
@@ -160,13 +161,13 @@ class ObjectOp(object):
self.opSetDefaultValues(obj)
@waiting_effects
- def _buildPathArea(self, obj, baseobject, start=None, getsim=False):
+ def _buildPathArea(self, obj, baseobject, isHole, start, getsim):
PathLog.track()
area = Path.Area()
area.setPlane(makeWorkplane(baseobject))
area.add(baseobject)
- areaParams = self.opAreaParams(obj)
+ areaParams = self.opAreaParams(obj, isHole)
heights = [i for i in self.depthparams]
PathLog.debug('depths: {}'.format(heights))
@@ -180,7 +181,7 @@ class ObjectOp(object):
shapelist = [sec.getShape() for sec in sections]
PathLog.debug("shapelist = %s" % shapelist)
- pathParams = self.opPathParams(obj)
+ pathParams = self.opPathParams(obj, isHole)
pathParams['shapes'] = shapelist
pathParams['feedrate'] = self.horizFeed
pathParams['feedrate_v'] = self.vertFeed
@@ -259,9 +260,9 @@ class ObjectOp(object):
shapes = self.opShapes(obj, commandlist)
sims = []
- for shape in shapes:
+ for (shape, isHole) in shapes:
try:
- (pp, sim) = self._buildPathArea(obj, shape, start, getsim)
+ (pp, sim) = self._buildPathArea(obj, shape, isHole, start, getsim)
commandlist.extend(pp.Commands)
sims.append(sim)
except Exception as e:
diff --git a/src/Mod/Path/PathScripts/PathAreaOpGui.py b/src/Mod/Path/PathScripts/PathAreaOpGui.py
index 32f0169fea..24385e816d 100644
--- a/src/Mod/Path/PathScripts/PathAreaOpGui.py
+++ b/src/Mod/Path/PathScripts/PathAreaOpGui.py
@@ -52,9 +52,7 @@ class ViewProvider(object):
def __init__(self, vobj):
PathLog.track()
vobj.Proxy = self
-
- #for sel in FreeCADGui.Selection.getSelectionEx():
- # if sel[0].HasSubObjects:
+ self.deleteOnReject = True
def attach(self, vobj):
PathLog.track()
@@ -190,6 +188,9 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
return self.supports & PathAreaOp.FeatureBaseEdges
def supportsFaces(self):
return self.supports & PathAreaOp.FeatureBaseFaces
+ def supportsPanels(self):
+ return self.supports & PathAreaOp.FeatureBasePanels
+
def featureName(self):
if self.supportsEdges() and self.supportsFaces():
return 'features'
@@ -200,19 +201,22 @@ class TaskPanelBaseGeometryPage(TaskPanelPage):
return 'nothing'
def addBaseGeometry(self, selection):
+ PathLog.track(selection)
if len(selection) != 1:
PathLog.error(translate("PathProject", "Please select %s from a single solid" % self.featureName()))
return False
sel = selection[0]
- if not sel.HasSubObjects:
- PathLog.error(translate("PathProject", "Please select %s of a solid" % self.featureName()))
- return False
- if not self.supportsEdges() and selection[0].SubObjects[0].ShapeType == "Edge":
- PathLog.error(translate("PathProject", "Please select only %s of a solid" % self.featureName()))
- return False
- if not self.supportsFaces() and selection[0].SubObjects[0].ShapeType == "Face":
- PathLog.error(translate("PathProject", "Please select only %s of a solid" % self.featureName()))
- return False
+ if sel.HasSubObjects:
+ if not self.supportsEdges() and selection[0].SubObjects[0].ShapeType == "Edge":
+ PathLog.error(translate("PathProject", "Please select only %s of a solid" % self.featureName()))
+ return False
+ if not self.supportsFaces() and selection[0].SubObjects[0].ShapeType == "Face":
+ PathLog.error(translate("PathProject", "Please select only %s of a solid" % self.featureName()))
+ return False
+ else:
+ if not self.supportsPanels() or not 'Panel' in sel.Object.Name:
+ PathLog.error(translate("PathProject", "Please select %s of a solid" % self.featureName()))
+ return False
for sub in sel.SubElementNames:
self.obj.Proxy.addBase(self.obj, sel.Object, sub)
@@ -409,7 +413,7 @@ class TaskPanel(object):
return int(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Apply | QtGui.QDialogButtonBox.Cancel)
def setupUi(self):
- PathLog.track()
+ PathLog.track(self.deleteOnReject)
if self.deleteOnReject and PathAreaOp.FeatureBaseGeometry & self.obj.Proxy.opFeatures(self.obj):
sel = FreeCADGui.Selection.getSelectionEx()
diff --git a/src/Mod/Path/PathScripts/PathContour.py b/src/Mod/Path/PathScripts/PathContour.py
index b7104fd285..fa6f01c324 100644
--- a/src/Mod/Path/PathScripts/PathContour.py
+++ b/src/Mod/Path/PathScripts/PathContour.py
@@ -123,12 +123,12 @@ class ObjectContour(PathAreaOp.ObjectOp):
for shape in shapes:
f = Part.makeFace([shape], 'Part::FaceMakerSimple')
thickness = baseobject.Group[0].Source.Thickness
- return [f.extrude(FreeCAD.Vector(0, 0, thickness))]
+ return [(f.extrude(FreeCAD.Vector(0, 0, thickness)), False)]
if hasattr(baseobject, "Shape") and not isPanel:
- return [PathUtils.getEnvelope(partshape=baseobject.Shape, subshape=None, depthparams=self.depthparams)]
+ return [(PathUtils.getEnvelope(partshape=baseobject.Shape, subshape=None, depthparams=self.depthparams), False)]
- def opAreaParams(self, obj):
+ def opAreaParams(self, obj, isHole):
params = {'Fill': 0, 'Coplanar': 2}
if obj.UseComp is False:
@@ -143,7 +143,7 @@ class ObjectContour(PathAreaOp.ObjectOp):
params['MiterLimit'] = obj.MiterLimit
return params
- def opPathParams(self, obj):
+ def opPathParams(self, obj, isHole):
params = {}
if obj.Direction == 'CCW':
params['orientation'] = 0
diff --git a/src/Mod/Path/PathScripts/PathContourGui.py b/src/Mod/Path/PathScripts/PathContourGui.py
index f4311f7fb8..66ac30e36f 100644
--- a/src/Mod/Path/PathScripts/PathContourGui.py
+++ b/src/Mod/Path/PathScripts/PathContourGui.py
@@ -86,8 +86,6 @@ def Create(name):
obj = PathContour.Create(name)
vobj = ViewProviderContour(obj.ViewObject)
- obj.ViewObject.Proxy.deleteOnReject = True
-
FreeCAD.ActiveDocument.commitTransaction()
obj.ViewObject.startEditing()
return obj
diff --git a/src/Mod/Path/PathScripts/PathPocket.py b/src/Mod/Path/PathScripts/PathPocket.py
index 2de69e9496..664e72ccca 100644
--- a/src/Mod/Path/PathScripts/PathPocket.py
+++ b/src/Mod/Path/PathScripts/PathPocket.py
@@ -75,7 +75,7 @@ class ObjectPocket(PathAreaOp.ObjectOp):
PathLog.warning("No job object found (%s), or job has no Base." % job)
return None
- def opAreaParams(self, obj):
+ def opAreaParams(self, obj, isHole):
params = {}
params['Fill'] = 0
params['Coplanar'] = 0
@@ -91,7 +91,7 @@ class ObjectPocket(PathAreaOp.ObjectOp):
params['PocketMode'] = Pattern.index(obj.OffsetPattern) + 1
return params
- def opPathParams(self, obj):
+ def opPathParams(self, obj, isHole):
params = {}
# if MinTravel is turned on, set path sorting to 3DSort
@@ -123,13 +123,13 @@ class ObjectPocket(PathAreaOp.ObjectOp):
env = PathUtils.getEnvelope(baseobject.Shape, subshape=shape, depthparams=self.depthparams)
obj.removalshape = env.cut(baseobject.Shape)
- removalshapes.append(obj.removalshape)
+ removalshapes.append((obj.removalshape, False))
else: # process the job base object as a whole
PathLog.debug("processing the whole job base object")
env = PathUtils.getEnvelope(baseobject.Shape, subshape=None, depthparams=self.depthparams)
obj.removalshape = env.cut(baseobject.Shape)
- removalshapes = [obj.removalshape]
+ removalshapes = [(obj.removalshape, False)]
return removalshapes
def opSetDefaultValues(self, obj):
diff --git a/src/Mod/Path/PathScripts/PathPocketGui.py b/src/Mod/Path/PathScripts/PathPocketGui.py
index aeb7ccbbbb..277c0c58f1 100644
--- a/src/Mod/Path/PathScripts/PathPocketGui.py
+++ b/src/Mod/Path/PathScripts/PathPocketGui.py
@@ -92,8 +92,6 @@ def Create(name):
obj = PathPocket.Create(name)
vobj = ViewProviderPocket(obj.ViewObject)
- obj.ViewObject.Proxy.deleteOnReject = True
-
FreeCAD.ActiveDocument.commitTransaction()
obj.ViewObject.startEditing()
return obj
diff --git a/src/Mod/Path/PathScripts/PathProfile.py b/src/Mod/Path/PathScripts/PathProfile.py
index 8738166f5d..5d9db8d8f6 100644
--- a/src/Mod/Path/PathScripts/PathProfile.py
+++ b/src/Mod/Path/PathScripts/PathProfile.py
@@ -22,24 +22,20 @@
# * *
# ***************************************************************************
-import FreeCAD
-import Path
-import numpy
import ArchPanel
+import FreeCAD
import Part
-
-from PathScripts import PathUtils
-from PathScripts.PathUtils import depth_params
+import Path
+import PathScripts.PathAreaOp as PathAreaOp
import PathScripts.PathLog as PathLog
+import PathScripts.PathUtils as PathUtils
+import numpy
-PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule())
-#PathLog.trackModule('PathProfile')
-#FreeCAD.setLogLevel('Path.Area', 0)
-
-if FreeCAD.GuiUp:
- import FreeCADGui
- from PySide import QtCore, QtGui
+from PathScripts.PathUtils import depth_params
+from PySide import QtCore
+PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule())
+PathLog.trackModule(PathLog.thisModule())
# Qt tanslation handling
def translate(context, text, disambig=None):
@@ -52,27 +48,9 @@ __url__ = "http://www.freecadweb.org"
"""Path Profile object and FreeCAD command"""
-class ObjectProfile:
+class ObjectProfile(PathAreaOp.ObjectOp):
- def __init__(self, obj):
- obj.addProperty("App::PropertyLinkSubList", "Base", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The base geometry of this toolpath"))
- obj.addProperty("App::PropertyBool", "Active", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "Make False, to prevent operation from generating code"))
- obj.addProperty("App::PropertyString", "Comment", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "An optional comment for this profile"))
- obj.addProperty("App::PropertyString", "UserLabel", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "User Assigned Label"))
-
- # Tool Properties
- obj.addProperty("App::PropertyLink", "ToolController", "Path", QtCore.QT_TRANSLATE_NOOP("App::Property", "The tool controller that will be used to calculate the path"))
-
- # Depth Properties
- obj.addProperty("App::PropertyDistance", "ClearanceHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "The height needed to clear clamps and obstructions"))
- obj.addProperty("App::PropertyDistance", "SafeHeight", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Rapid Safety Height between locations."))
- obj.addProperty("App::PropertyDistance", "StepDown", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Incremental Step Down of Tool"))
- obj.addProperty("App::PropertyDistance", "StartDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Starting Depth of Tool- first cut depth in Z"))
- obj.addProperty("App::PropertyDistance", "FinalDepth", "Depth", QtCore.QT_TRANSLATE_NOOP("App::Property", "Final Depth of Tool- lowest value in Z"))
-
- # Start Point Properties
- obj.addProperty("App::PropertyVector", "StartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "The start point of this path"))
- obj.addProperty("App::PropertyBool", "UseStartPoint", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "make True, if specifying a Start Point"))
+ def initOperation(self, obj):
# Profile Properties
obj.addProperty("App::PropertyEnumeration", "Side", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property", "Side of edge that tool should cut"))
@@ -88,44 +66,35 @@ class ObjectProfile:
obj.JoinType = ['Round', 'Square', 'Miter'] # this is the direction that the Contour runs
obj.addProperty("App::PropertyFloat", "MiterLimit", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property", "Maximum distance before a miter join is truncated"))
- # Debug Parameters
- obj.addProperty("App::PropertyString", "AreaParams", "Path")
- obj.setEditorMode('AreaParams', 2) # hide
- obj.addProperty("App::PropertyString", "PathParams", "Path")
- obj.setEditorMode('PathParams', 2) # hide
- obj.addProperty("Part::PropertyPartShape", "removalshape", "Path")
- obj.setEditorMode('removalshape', 2) # hide
-
- if FreeCAD.GuiUp:
- _ViewProviderProfile(obj.ViewObject)
-
obj.Proxy = self
- def __getstate__(self):
- return None
+ def opSetDefaultValues(self, obj):
+ obj.Side = "Outside"
+ obj.OffsetExtra = 0.0
+ obj.Direction = "CW"
+ obj.UseComp = True
+ obj.processHoles = False
+ obj.processPerimeter = True
+ obj.JoinType = "Round"
+ obj.MiterLimit = 0.1
- def __setstate__(self, state):
- return None
-
- def onChanged(self, obj, prop):
+ def onOpChanged(self, obj, prop):
if prop == "UseComp":
if not obj.UseComp:
obj.setEditorMode('Side', 2)
else:
obj.setEditorMode('Side', 0)
- if prop in ['AreaParams', 'PathParams', 'removalshape']:
- obj.setEditorMode(prop, 2)
- obj.setEditorMode('MiterLimit', 2)
- if obj.JoinType == 'Miter':
- obj.setEditorMode('MiterLimit', 0)
+ if prop == "JoinType":
+ obj.setEditorMode('MiterLimit', 2)
+ if obj.JoinType == 'Miter':
+ obj.setEditorMode('MiterLimit', 0)
- def addprofilebase(self, obj, ss, sub=""):
- baselist = obj.Base
- if len(baselist) == 0: # When adding the first base object, guess at heights
+ if prop == 'Base' and len(obj.Base) == 1:
try:
- bb = ss.Shape.BoundBox # parent boundbox
- subobj = ss.Shape.getElement(sub)
+ (base, sub) = obj.Base[0]
+ bb = base.BoundBox # parent boundbox
+ subobj = base.getElement(sub)
fbb = subobj.BoundBox # feature boundbox
obj.StartDepth = bb.ZMax
obj.ClearanceHeight = bb.ZMax + 5.0
@@ -141,39 +110,44 @@ class ObjectProfile:
obj.FinalDepth = fbb.ZMin
else: # catch all
obj.FinalDepth = bb.ZMin
- except:
+
+ if bb.XLength == fbb.XLength and bb.YLength == fbb.YLength:
+ obj.Side = "Outside"
+ else:
+ obj.Side = "Inside"
+
+ except Exception as e:
+ PathLog.error(translate("PathPocket", "Error in calculating depths: %s" % e))
obj.StartDepth = 5.0
obj.ClearanceHeight = 10.0
obj.SafeHeight = 8.0
-
- if bb.XLength == fbb.XLength and bb.YLength == fbb.YLength:
obj.Side = "Outside"
- else:
- obj.Side = "Inside"
- item = (ss, sub)
- if item in baselist:
- FreeCAD.Console.PrintWarning("this object already in the list" + "\n")
- else:
- baselist.append(item)
- obj.Base = baselist
- self.execute(obj)
+ def opFeatures(self, obj):
+ return PathAreaOp.FeatureTool | PathAreaOp.FeatureDepths | PathAreaOp.FeatureHeights | PathAreaOp.FeatureStartPoint | PathAreaOp.FeatureBaseFaces
- def _buildPathArea(self, obj, baseobject, isHole=False, start=None, getsim=False):
- PathLog.track()
- profile = Path.Area()
- profile.setPlane(Part.makeCircle(10))
- profile.add(baseobject)
+ def opUseProjection(self, obj):
+ return True
- profileparams = {'Fill': 0,
- 'Coplanar': 2,
- 'Offset': 0.0,
- 'SectionCount': -1}
+ def opShapeForDepths(self, obj):
+ job = PathUtils.findParentJob(obj)
+ if job and job.Base:
+ PathLog.debug("job=%s base=%s shape=%s" % (job, job.Base, job.Base.Shape))
+ return job.Base.Shape
+ PathLog.warning("No job object found (%s), or job has no Base." % job)
+ return None
+
+ def opAreaParams(self, obj, isHole):
+ params = {}
+ params['Fill'] = 0
+ params['Coplanar'] = 2
+ params['Offset'] = 0.0
+ params['SectionCount'] = -1
offsetval = 0
if obj.UseComp:
- offsetval = self.radius+obj.OffsetExtra.Value
+ offsetval = self.radius + obj.OffsetExtra.Value
if obj.Side == 'Inside':
offsetval = 0 - offsetval
@@ -181,31 +155,17 @@ class ObjectProfile:
if isHole:
offsetval = 0 - offsetval
- profileparams['Offset'] = offsetval
+ params['Offset'] = offsetval
jointype = ['Round', 'Square', 'Miter']
- profileparams['JoinType'] = jointype.index(obj.JoinType)
+ params['JoinType'] = jointype.index(obj.JoinType)
if obj.JoinType == 'Miter':
- profileparams['MiterLimit'] = obj.MiterLimit
+ params['MiterLimit'] = obj.MiterLimit
+ return params
- profile.setParams(**profileparams)
- obj.AreaParams = str(profile.getParams())
-
- # PathLog.debug("About to profile with params: {}".format(profileparams))
- PathLog.debug("About to profile with params: {}".format(profile.getParams()))
-
- heights = [i for i in self.depthparams]
-
- sections = profile.makeSections(mode=0, project=True, heights=heights)
- shapelist = [sec.getShape() for sec in sections]
-
- params = {'shapes': shapelist,
- 'feedrate': self.horizFeed,
- 'feedrate_v': self.vertFeed,
- 'verbose': True,
- 'resume_height': obj.StepDown.Value,
- 'retraction': obj.ClearanceHeight.Value}
+ def opPathParams(self, obj, isHole):
+ params = {}
# Reverse the direction for holes
if isHole:
@@ -217,62 +177,10 @@ class ObjectProfile:
params['orientation'] = 0
else:
params['orientation'] = 1
+ return params
- if obj.UseStartPoint is True and obj.StartPoint is not None:
- params['start'] = obj.StartPoint
-
- pp = Path.fromShapes(**params)
-
- obj.PathParams = str({key: value for key, value in params.items() if key != 'shapes'})
-
- PathLog.debug("Generating Path with params: {}".format(params))
- PathLog.debug(pp)
-
- simobj = None
- if getsim:
- profileparams['Thicken'] = True
- profileparams['ToolRadius'] = self.radius - self.radius * .005
- profile.setParams(**profileparams)
- sec = profile.makeSections(mode=0, project=False, heights=heights)[-1].getShape()
- simobj = sec.extrude(FreeCAD.Vector(0, 0, baseobject.BoundBox.ZMax))
-
- return pp, simobj
-
- def execute(self, obj, getsim=False):
- import Part
-
- if not obj.Active:
- path = Path.Path("(inactive operation)")
- obj.Path = path
- obj.ViewObject.Visibility = False
- return
-
- self.depthparams = depth_params(
- clearance_height=obj.ClearanceHeight.Value,
- safe_height=obj.SafeHeight.Value,
- start_depth=obj.StartDepth.Value,
- step_down=obj.StepDown.Value,
- z_finish_step=0.0,
- final_depth=obj.FinalDepth.Value,
- user_depths=None)
-
- commandlist = []
- toolLoad = obj.ToolController
- if toolLoad is None or toolLoad.ToolNumber == 0:
- FreeCAD.Console.PrintError("No Tool Controller is selected. We need a tool to build a Path.")
- return
- else:
- self.vertFeed = toolLoad.VertFeed.Value
- self.horizFeed = toolLoad.HorizFeed.Value
- self.vertRapid = toolLoad.VertRapid.Value
- self.horizRapid = toolLoad.HorizRapid.Value
- tool = toolLoad.Proxy.getTool(toolLoad)
- if not tool or tool.Diameter == 0:
- FreeCAD.Console.PrintError("No Tool found or diameter is zero. We need a tool to build a Path.")
- return
- else:
- self.radius = tool.Diameter/2
+ def opShapes(self, obj, commandlist):
commandlist.append(Path.Command("(" + obj.Label + ")"))
if obj.UseComp:
@@ -280,13 +188,13 @@ class ObjectProfile:
else:
commandlist.append(Path.Command("(Uncompensated Tool Path)"))
- parentJob = PathUtils.findParentJob(obj)
- if parentJob is None:
- return
- baseobject = parentJob.Base
- if baseobject is None:
+ job = PathUtils.findParentJob(obj)
+ if not job or not job.Base:
return
+ baseobject = job.Base
+ shapes = []
+
if obj.Base: # The user has selected subobjects from the base. Process each.
holes = []
faces = []
@@ -306,408 +214,37 @@ class ObjectProfile:
drillable = PathUtils.isDrillable(baseobject.Shape, wire)
if (drillable and obj.processCircles) or (not drillable and obj.processHoles):
env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, depthparams=self.depthparams)
- try:
- (pp, sim) = self._buildPathArea(obj, baseobject=env, isHole=True, start=None, getsim=getsim)
- commandlist.extend(pp.Commands)
- except Exception as e:
- FreeCAD.Console.PrintError(e)
- FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
+ shapes.append((env, True))
if len(faces) > 0:
profileshape = Part.makeCompound(faces)
if obj.processPerimeter:
env = PathUtils.getEnvelope(baseobject.Shape, subshape=profileshape, depthparams=self.depthparams)
- try:
- (pp, sim) = self._buildPathArea(obj, baseobject=env, start=None, getsim=getsim)
- commandlist.extend(pp.Commands)
- except Exception as e:
- FreeCAD.Console.PrintError(e)
- FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
+ shapes.append((env, False))
else: # Try to build targets from the job base
if hasattr(baseobject, "Proxy"):
if isinstance(baseobject.Proxy, ArchPanel.PanelSheet): # process the sheet
if obj.processCircles or obj.processHoles:
- shapes = baseobject.Proxy.getHoles(baseobject, transform=True)
- for shape in shapes:
+ for shape in baseobject.Proxy.getHoles(baseobject, transform=True):
for wire in shape.Wires:
drillable = PathUtils.isDrillable(baseobject.Proxy, wire)
if (drillable and obj.processCircles) or (not drillable and obj.processHoles):
f = Part.makeFace(wire, 'Part::FaceMakerSimple')
env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, depthparams=self.depthparams)
- try:
- (pp, sim) = self._buildPathArea(obj, baseobject=env, isHole=True, start=None, getsim=getsim)
- commandlist.extend(pp.Commands)
- except Exception as e:
- FreeCAD.Console.PrintError(e)
- FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
+ shapes.append((env, True))
if obj.processPerimeter:
- shapes = baseobject.Proxy.getOutlines(baseobject, transform=True)
- for shape in shapes:
+ for shape in baseobject.Proxy.getOutlines(baseobject, transform=True):
for wire in shape.Wires:
f = Part.makeFace(wire, 'Part::FaceMakerSimple')
env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, depthparams=self.depthparams)
- try:
- (pp, sim) = self._buildPathArea(obj, baseobject=env, isHole=False, start=None, getsim=getsim)
- commandlist.extend(pp.Commands)
- except Exception as e:
- FreeCAD.Console.PrintError(e)
- FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
+ shapes.append((env, False))
- # Let's finish by rapid to clearance...just for safety
- commandlist.append(Path.Command("G0", {"Z": obj.ClearanceHeight.Value}))
+ return shapes
- path = Path.Path(commandlist)
- obj.Path = path
-
-
-class _ViewProviderProfile:
-
- def __init__(self, vobj):
- vobj.Proxy = self
-
- def attach(self, vobj):
- self.Object = vobj.Object
- return
-
- def deleteObjectsOnReject(self):
- return hasattr(self, 'deleteOnReject') and self.deleteOnReject
-
- def setEdit(self, vobj, mode=0):
- FreeCADGui.Control.closeDialog()
- taskd = TaskPanel(vobj.Object, self.deleteObjectsOnReject())
- taskd.obj = vobj.Object
- FreeCADGui.Control.showDialog(taskd)
- taskd.setupUi()
- self.deleteOnReject = False
- return True
-
- def getIcon(self):
- return ":/icons/Path-Profile-Face.svg"
-
- def __getstate__(self):
- return None
-
- def __setstate__(self, state):
- return None
-
-
-class _CommandSetStartPoint:
- def GetResources(self):
- return {'Pixmap': 'Path-StartPoint',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Profile", "Pick Start Point"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Profile", "Pick Start Point")}
-
- def IsActive(self):
- return FreeCAD.ActiveDocument is not None
-
- def setpoint(self, point, o):
- obj = FreeCADGui.Selection.getSelection()[0]
- obj.StartPoint.x = point.x
- obj.StartPoint.y = point.y
-
- def Activated(self):
-
- FreeCADGui.Snapper.getPoint(callback=self.setpoint)
-
-
-class CommandPathProfile:
- def GetResources(self):
- return {'Pixmap': 'Path-Profile-Face',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("PathProfile", "Face Profile"),
- 'Accel': "P, F",
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathProfile", "Profile based on face or faces")}
-
- 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):
- ztop = 10.0
- zbottom = 0.0
-
- FreeCAD.ActiveDocument.openTransaction(translate("Path", "Create a Profile"))
- FreeCADGui.addModule("PathScripts.PathProfile")
- FreeCADGui.doCommand('obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", "Profile")')
- FreeCADGui.doCommand('PathScripts.PathProfile.ObjectProfile(obj)')
-
- FreeCADGui.doCommand('obj.Active = True')
-
- FreeCADGui.doCommand('obj.ClearanceHeight = ' + str(ztop + 10.0))
- FreeCADGui.doCommand('obj.StepDown = 1.0')
- FreeCADGui.doCommand('obj.StartDepth= ' + str(ztop))
- FreeCADGui.doCommand('obj.FinalDepth=' + str(zbottom))
-
- FreeCADGui.doCommand('obj.SafeHeight = ' + str(ztop + 2.0))
- FreeCADGui.doCommand('obj.Side = "Outside"')
- FreeCADGui.doCommand('obj.OffsetExtra = 0.0')
- FreeCADGui.doCommand('obj.Direction = "CW"')
- FreeCADGui.doCommand('obj.UseComp = True')
- FreeCADGui.doCommand('obj.processHoles = False')
- FreeCADGui.doCommand('obj.processPerimeter = True')
- FreeCADGui.doCommand('obj.JoinType = "Round"')
- FreeCADGui.doCommand('obj.MiterLimit =' + str(0.1))
-
- FreeCADGui.doCommand('obj.ViewObject.Proxy.deleteOnReject = True')
- FreeCADGui.doCommand('PathScripts.PathUtils.addToJob(obj)')
- FreeCADGui.doCommand('obj.ToolController = PathScripts.PathUtils.findToolController(obj)')
-
- FreeCAD.ActiveDocument.commitTransaction()
- FreeCADGui.doCommand('obj.ViewObject.startEditing()')
-
-
-class TaskPanel:
- def __init__(self, obj, deleteOnReject):
- FreeCAD.ActiveDocument.openTransaction(translate("Path_Profile", "Profile Operation"))
- self.form = FreeCADGui.PySideUic.loadUi(":/panels/ProfileEdit.ui")
- self.isDirty = True
- self.deleteOnReject = deleteOnReject
- self.obj = obj
-
- def accept(self):
- FreeCADGui.Control.closeDialog()
- FreeCADGui.ActiveDocument.resetEdit()
- FreeCAD.ActiveDocument.commitTransaction()
- FreeCADGui.Selection.removeObserver(self.s)
- if self.isDirty:
- FreeCAD.ActiveDocument.recompute()
-
- def reject(self):
- FreeCADGui.Control.closeDialog()
- FreeCADGui.ActiveDocument.resetEdit()
- FreeCAD.ActiveDocument.abortTransaction()
- FreeCADGui.Selection.removeObserver(self.s)
- if self.deleteOnReject:
- FreeCAD.ActiveDocument.openTransaction(translate("Path_Profile", "Uncreate Profile Operation"))
- FreeCAD.ActiveDocument.removeObject(self.obj.Name)
- FreeCAD.ActiveDocument.commitTransaction()
- FreeCAD.ActiveDocument.recompute()
-
- def clicked(self, button):
- if button == QtGui.QDialogButtonBox.Apply:
- self.getFields()
- self.obj.Proxy.execute(self.obj)
- self.isDirty = False
-
- def getFields(self):
- if self.obj:
-
- if hasattr(self.obj, "StartDepth"):
- self.obj.StartDepth = FreeCAD.Units.Quantity(self.form.startDepth.text()).Value
- if hasattr(self.obj, "FinalDepth"):
- self.obj.FinalDepth = FreeCAD.Units.Quantity(self.form.finalDepth.text()).Value
- if hasattr(self.obj, "StepDown"):
- self.obj.StepDown = FreeCAD.Units.Quantity(self.form.stepDown.text()).Value
- if hasattr(self.obj, "SafeHeight"):
- self.obj.SafeHeight = FreeCAD.Units.Quantity(self.form.safeHeight.text()).Value
- if hasattr(self.obj, "ClearanceHeight"):
- self.obj.ClearanceHeight = FreeCAD.Units.Quantity(self.form.clearanceHeight.text()).Value
- if hasattr(self.obj, "OffsetExtra"):
- self.obj.OffsetExtra = FreeCAD.Units.Quantity(self.form.extraOffset.text()).Value
- if hasattr(self.obj, "UseComp"):
- self.obj.UseComp = self.form.useCompensation.isChecked()
- if hasattr(self.obj, "UseStartPoint"):
- self.obj.UseStartPoint = self.form.useStartPoint.isChecked()
- if hasattr(self.obj, "Side"):
- self.obj.Side = str(self.form.cutSide.currentText())
- if hasattr(self.obj, "Direction"):
- self.obj.Direction = str(self.form.direction.currentText())
- if hasattr(self.obj, "processHoles"):
- self.obj.processHoles = self.form.processHoles.isChecked()
- if hasattr(self.obj, "processPerimeter"):
- self.obj.processPerimeter = self.form.processPerimeter.isChecked()
- if hasattr(self.obj, "processCircles"):
- self.obj.processCircles = self.form.processCircles.isChecked()
- if hasattr(self.obj, "ToolController"):
- PathLog.debug("name: {}".format(self.form.uiToolController.currentText()))
- tc = PathUtils.findToolController(self.obj, self.form.uiToolController.currentText())
- self.obj.ToolController = tc
-
- self.isDirty = True
-
- def setFields(self):
- self.form.startDepth.setText(FreeCAD.Units.Quantity(self.obj.StartDepth.Value, FreeCAD.Units.Length).UserString)
- self.form.finalDepth.setText(FreeCAD.Units.Quantity(self.obj.FinalDepth.Value, FreeCAD.Units.Length).UserString)
- self.form.stepDown.setText(FreeCAD.Units.Quantity(self.obj.StepDown.Value, FreeCAD.Units.Length).UserString)
- self.form.safeHeight.setText(FreeCAD.Units.Quantity(self.obj.SafeHeight.Value, FreeCAD.Units.Length).UserString)
- self.form.clearanceHeight.setText(FreeCAD.Units.Quantity(self.obj.ClearanceHeight.Value, FreeCAD.Units.Length).UserString)
- self.form.extraOffset.setText(FreeCAD.Units.Quantity(self.obj.OffsetExtra.Value, FreeCAD.Units.Length).UserString)
- self.form.useCompensation.setChecked(self.obj.UseComp)
- self.form.useStartPoint.setChecked(self.obj.UseStartPoint)
- self.form.processHoles.setChecked(self.obj.processHoles)
- self.form.processPerimeter.setChecked(self.obj.processPerimeter)
- self.form.processCircles.setChecked(self.obj.processCircles)
-
- index = self.form.cutSide.findText(
- self.obj.Side, QtCore.Qt.MatchFixedString)
- if index >= 0:
- self.form.cutSide.blockSignals(True)
- self.form.cutSide.setCurrentIndex(index)
- self.form.cutSide.blockSignals(False)
-
- index = self.form.direction.findText(
- self.obj.Direction, QtCore.Qt.MatchFixedString)
- if index >= 0:
- self.form.direction.blockSignals(True)
- self.form.direction.setCurrentIndex(index)
- self.form.direction.blockSignals(False)
-
- controllers = PathUtils.getToolControllers(self.obj)
- labels = [c.Label for c in controllers]
- self.form.uiToolController.blockSignals(True)
- self.form.uiToolController.addItems(labels)
- self.form.uiToolController.blockSignals(False)
-
- if self.obj.ToolController is not None:
- index = self.form.uiToolController.findText(
- self.obj.ToolController.Label, QtCore.Qt.MatchFixedString)
- PathLog.debug("searching for TC label {}. Found Index: {}".format(self.obj.ToolController.Label, index))
- if index >= 0:
- self.form.uiToolController.blockSignals(True)
- self.form.uiToolController.setCurrentIndex(index)
- self.form.uiToolController.blockSignals(False)
- else:
- self.obj.ToolController = PathUtils.findToolController(self.obj)
-
- self.form.baseList.blockSignals(True)
- for i in self.obj.Base:
- for sub in i[1]:
- self.form.baseList.addItem(i[0].Name + "." + sub)
- self.form.baseList.blockSignals(False)
-
- self.form.update()
-
- def open(self):
- self.s = SelObserver()
- # install the function mode resident
- FreeCADGui.Selection.addObserver(self.s)
-
- def addBase(self):
- # check that the selection contains exactly what we want
- selection = FreeCADGui.Selection.getSelectionEx()
-
- if len(selection) != 1:
- FreeCAD.Console.PrintError(translate("PathProject", "Please select only faces from one solid\n"))
- return
- sel = selection[0]
- if not sel.HasSubObjects:
- FreeCAD.Console.PrintError(translate("PathProject", "Please select faces from one solid\n"))
- return
- if not selection[0].SubObjects[0].ShapeType == "Face":
- FreeCAD.Console.PrintError(translate("PathProject", "Please select faces from one solid\n"))
- return
-
- for i in sel.SubElementNames:
- self.obj.Proxy.addprofilebase(self.obj, sel.Object, i)
-
- self.setFields() # defaults may have changed. Reload.
- self.form.baseList.clear()
-
- for i in self.obj.Base:
- for sub in i[1]:
- self.form.baseList.addItem(i[0].Name + "." + sub)
-
- def deleteBase(self):
- dlist = self.form.baseList.selectedItems()
- newlist = []
- for d in dlist:
- for i in self.obj.Base:
- if i[0].Name != d.text().partition(".")[0] or i[1] != d.text().partition(".")[2]:
- newlist.append(i)
- self.form.baseList.takeItem(self.form.baseList.row(d))
- self.obj.Base = newlist
- self.obj.Proxy.execute(self.obj)
- FreeCAD.ActiveDocument.recompute()
-
- def itemActivated(self):
- FreeCADGui.Selection.clearSelection()
- slist = self.form.baseList.selectedItems()
- for i in slist:
- objstring = i.text().partition(".")
- obj = FreeCAD.ActiveDocument.getObject(objstring[0])
- if objstring[2] != "":
- FreeCADGui.Selection.addSelection(obj, objstring[2])
- else:
- FreeCADGui.Selection.addSelection(obj)
-
- FreeCADGui.updateGui()
-
- def reorderBase(self):
- newlist = []
- for i in range(self.form.baseList.count()):
- s = self.form.baseList.item(i).text()
- objstring = s.partition(".")
-
- obj = FreeCAD.ActiveDocument.getObject(objstring[0])
- item = (obj, str(objstring[2]))
- newlist.append(item)
- self.obj.Base = newlist
-
- self.obj.Proxy.execute(self.obj)
- FreeCAD.ActiveDocument.recompute()
-
- def getStandardButtons(self):
- return int(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Apply | QtGui.QDialogButtonBox.Cancel)
-
- def setupUi(self):
-
- # Connect Signals and Slots
- # Base Controls
- self.form.baseList.itemSelectionChanged.connect(self.itemActivated)
- self.form.addBase.clicked.connect(self.addBase)
- self.form.deleteBase.clicked.connect(self.deleteBase)
- self.form.reorderBase.clicked.connect(self.reorderBase)
- self.form.uiToolController.currentIndexChanged.connect(self.getFields)
-
- # Depths
- self.form.startDepth.editingFinished.connect(self.getFields)
- self.form.finalDepth.editingFinished.connect(self.getFields)
- self.form.stepDown.editingFinished.connect(self.getFields)
-
- # Heights
- self.form.safeHeight.editingFinished.connect(self.getFields)
- self.form.clearanceHeight.editingFinished.connect(self.getFields)
-
- # operation
- self.form.cutSide.currentIndexChanged.connect(self.getFields)
- self.form.uiToolController.currentIndexChanged.connect(self.getFields)
- self.form.direction.currentIndexChanged.connect(self.getFields)
- self.form.useCompensation.clicked.connect(self.getFields)
- self.form.useStartPoint.clicked.connect(self.getFields)
- self.form.extraOffset.editingFinished.connect(self.getFields)
- self.form.processHoles.clicked.connect(self.getFields)
- self.form.processPerimeter.clicked.connect(self.getFields)
- self.form.processCircles.clicked.connect(self.getFields)
-
- self.setFields()
-
- sel = FreeCADGui.Selection.getSelectionEx()
- if len(sel) != 0 and sel[0].HasSubObjects:
- self.addBase()
-
-
-class SelObserver:
- def __init__(self):
- import PathScripts.PathSelection as PST
- PST.profileselect()
-
- def __del__(self):
- import PathScripts.PathSelection as PST
- PST.clear()
-
- def addSelection(self, doc, obj, sub, pnt):
- FreeCADGui.doCommand('Gui.Selection.addSelection(FreeCAD.ActiveDocument.' + obj + ')')
- FreeCADGui.updateGui()
-
-
-if FreeCAD.GuiUp:
- # register the FreeCAD command
- FreeCADGui.addCommand('Path_Profile', CommandPathProfile())
- FreeCADGui.addCommand('Set_StartPoint', _CommandSetStartPoint())
-
-FreeCAD.Console.PrintLog("Loading PathProfile... done\n")
+def Create(name):
+ obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name)
+ proxy = ObjectProfile(obj)
+ return obj
diff --git a/src/Mod/Path/PathScripts/PathProfileGui.py b/src/Mod/Path/PathScripts/PathProfileGui.py
new file mode 100644
index 0000000000..c34b750741
--- /dev/null
+++ b/src/Mod/Path/PathScripts/PathProfileGui.py
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+
+# ***************************************************************************
+# * *
+# * Copyright (c) 2017 sliptonic *
+# * *
+# * 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 Path
+import PathScripts.PathAreaOpGui as PathAreaOpGui
+import PathScripts.PathLog as PathLog
+import PathScripts.PathProfile as PathProfile
+import PathScripts.PathSelection as PathSelection
+
+from PathScripts import PathUtils
+from PySide import QtCore, QtGui
+
+def translate(context, text, disambig=None):
+ return QtCore.QCoreApplication.translate(context, text, disambig)
+
+class TaskPanelOpPage(PathAreaOpGui.TaskPanelPage):
+
+ def getForm(self):
+ return FreeCADGui.PySideUic.loadUi(":/panels/PageOpProfileEdit.ui")
+
+ def getFields(self, obj):
+ self.obj.OffsetExtra = FreeCAD.Units.Quantity(self.form.extraOffset.text()).Value
+ self.obj.UseComp = self.form.useCompensation.isChecked()
+ self.obj.UseStartPoint = self.form.useStartPoint.isChecked()
+ self.obj.Side = str(self.form.cutSide.currentText())
+ self.obj.Direction = str(self.form.direction.currentText())
+ self.obj.processHoles = self.form.processHoles.isChecked()
+ self.obj.processPerimeter = self.form.processPerimeter.isChecked()
+ self.obj.processCircles = self.form.processCircles.isChecked()
+
+ tc = PathUtils.findToolController(self.obj, self.form.toolController.currentText())
+ self.obj.ToolController = tc
+
+ def setFields(self, obj):
+ self.form.extraOffset.setText(FreeCAD.Units.Quantity(self.obj.OffsetExtra.Value, FreeCAD.Units.Length).UserString)
+ self.form.useCompensation.setChecked(self.obj.UseComp)
+ self.form.useStartPoint.setChecked(self.obj.UseStartPoint)
+ self.form.processHoles.setChecked(self.obj.processHoles)
+ self.form.processPerimeter.setChecked(self.obj.processPerimeter)
+ self.form.processCircles.setChecked(self.obj.processCircles)
+
+ self.selectInComboBox(self.obj.Side, self.form.cutSide)
+ self.selectInComboBox(self.obj.Direction, self.form.direction)
+ self.setupToolController(self.obj, self.form.toolController)
+
+ def getSignalsForUpdate(self, obj):
+ signals = []
+ signals.append(self.form.cutSide.currentIndexChanged)
+ signals.append(self.form.direction.currentIndexChanged)
+ signals.append(self.form.useCompensation.clicked)
+ signals.append(self.form.useStartPoint.clicked)
+ signals.append(self.form.extraOffset.editingFinished)
+ signals.append(self.form.processHoles.clicked)
+ signals.append(self.form.processPerimeter.clicked)
+ signals.append(self.form.processCircles.clicked)
+ return signals
+
+class ViewProviderProfile(PathAreaOpGui.ViewProvider):
+
+ def getTaskPanelOpPage(self, obj):
+ return TaskPanelOpPage(obj)
+
+ def getIcon(self):
+ return ":/icons/Path-Profile-Face.svg"
+
+ def getSelectionFactory(self):
+ return PathSelection.profileselect
+
+
+def Create(name):
+ FreeCAD.ActiveDocument.openTransaction(translate("Path", "Create a Profile"))
+ obj = PathProfile.Create(name)
+ vobj = ViewProviderProfile(obj.ViewObject)
+
+ FreeCAD.ActiveDocument.commitTransaction()
+ obj.ViewObject.startEditing()
+ return obj
+
+class CommandPathProfile:
+ def GetResources(self):
+ return {'Pixmap': 'Path-Profile-Face',
+ 'MenuText': QtCore.QT_TRANSLATE_NOOP("PathProfile", "Face Profile"),
+ 'Accel': "P, F",
+ 'ToolTip': QtCore.QT_TRANSLATE_NOOP("PathProfile", "Profile based on face or faces")}
+
+ 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):
+ return Create('Profile')
+
+FreeCADGui.addCommand('Path_Profile', CommandPathProfile())
+FreeCAD.Console.PrintLog("Loading PathProfileGui... done\n")