diff --git a/src/Mod/Path/PathScripts/PathAdaptive.py b/src/Mod/Path/PathScripts/PathAdaptive.py index f7b96cf96e..2c765c5d15 100644 --- a/src/Mod/Path/PathScripts/PathAdaptive.py +++ b/src/Mod/Path/PathScripts/PathAdaptive.py @@ -737,9 +737,19 @@ def SetupProperties(): return setup -def Create(name, obj=None): +def SetupProperties(): + setup = ["Side", "OperationType", "Tolerance", "StepOver", + "LiftDistance", "KeepToolDownRatio", "StockToLeave", + "ForceInsideOut", "FinishingProfile", "Stopped", + "StopProcessing", "UseHelixArcs", "AdaptiveInputState", + "AdaptiveOutputState", "HelixAngle", "HelixConeAngle", + "HelixDiameterLimit", "UseOutline"] + return setup + + +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Adaptive operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = PathAdaptive(obj, name) + obj.Proxy = PathAdaptive(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathCustom.py b/src/Mod/Path/PathScripts/PathCustom.py index acfca878d2..73c4b4097e 100644 --- a/src/Mod/Path/PathScripts/PathCustom.py +++ b/src/Mod/Path/PathScripts/PathCustom.py @@ -70,9 +70,9 @@ def SetupProperties(): return setup -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Custom operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - proxy = ObjectCustom(obj, name) + obj.Proxy = ObjectCustom(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathDeburr.py b/src/Mod/Path/PathScripts/PathDeburr.py index 51bbb96207..fbfdf7cf02 100644 --- a/src/Mod/Path/PathScripts/PathDeburr.py +++ b/src/Mod/Path/PathScripts/PathDeburr.py @@ -291,10 +291,9 @@ def SetupProperties(): return setup -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Deburr operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - - obj.Proxy = ObjectDeburr(obj, name) + obj.Proxy = ObjectDeburr(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathDressupPathBoundary.py b/src/Mod/Path/PathScripts/PathDressupPathBoundary.py index dc6d57f2f6..68eda29544 100644 --- a/src/Mod/Path/PathScripts/PathDressupPathBoundary.py +++ b/src/Mod/Path/PathScripts/PathDressupPathBoundary.py @@ -35,6 +35,11 @@ PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) # PathLog.trackModule(PathLog.thisModule()) +# Qt translation handling +def translate(context, text, disambig=None): + return QtCore.QCoreApplication.translate(context, text, disambig) + + def _vstr(v): if v: return "(%.2f, %.2f, %.2f)" % (v.x, v.y, v.z) @@ -77,7 +82,29 @@ class DressupPathBoundary(object): obj.Stock = None return True - def boundaryCommands(self, obj, begin, end, verticalFeed): + def execute(self, obj): + pb = PathBoundary(obj.Base, obj.Stock.Shape, obj.Inside) + obj.Path = pb.execute() +# Eclass + + +class PathBoundary: + """class PathBoundary... + This class requires a base operation, boundary shape, and optional inside boolean (default is True). + The `execute()` method returns a Path object with path commands limited to cut paths inside or outside + the provided boundary shape. + """ + + def __init__(self, baseOp, boundaryShape, inside=True): + self.baseOp = baseOp + self.boundary = boundaryShape + self.inside = inside + self.safeHeight = None + self.clearanceHeight = None + self.strG1ZsafeHeight = None + self.strG0ZclearanceHeight = None + + def boundaryCommands(self, begin, end, verticalFeed): PathLog.track(_vstr(begin), _vstr(end)) if end and PathGeom.pointsCoincide(begin, end): return [] @@ -94,117 +121,117 @@ class DressupPathBoundary(object): cmds.append(Path.Command('G1', {'Z': end.z, 'F': verticalFeed})) return cmds - def execute(self, obj): - if not obj.Base or not obj.Base.isDerivedFrom('Path::Feature') or not obj.Base.Path: - return + def execute(self): + if not self.baseOp or not self.baseOp.isDerivedFrom('Path::Feature') or not self.baseOp.Path: + return None - tc = PathDressup.toolController(obj.Base) + if len(self.baseOp.Path.Commands) == 0: + PathLog.warning("No Path Commands for %s" % self.baseOp.Label) + return [] - if len(obj.Base.Path.Commands) > 0: - self.safeHeight = float(PathUtil.opProperty(obj.Base, 'SafeHeight')) - self.clearanceHeight = float(PathUtil.opProperty(obj.Base, 'ClearanceHeight')) - self.strG1ZsafeHeight = Path.Command('G1', {'Z': self.safeHeight, 'F': tc.VertFeed.Value}) - self.strG0ZclearanceHeight = Path.Command('G0', {'Z': self.clearanceHeight}) + tc = PathDressup.toolController(self.baseOp) - boundary = obj.Stock.Shape - cmd = obj.Base.Path.Commands[0] - pos = cmd.Placement.Base # bogus m/c position to create first edge - bogusX = True - bogusY = True - commands = [cmd] - lastExit = None - for cmd in obj.Base.Path.Commands[1:]: - if cmd.Name in PathGeom.CmdMoveAll: - if bogusX == True : - bogusX = ( 'X' not in cmd.Parameters ) - if bogusY : - bogusY = ( 'Y' not in cmd.Parameters ) - edge = PathGeom.edgeForCmd(cmd, pos) - if edge: - inside = edge.common(boundary).Edges - outside = edge.cut(boundary).Edges - if not obj.Inside: # UI "inside boundary" param - tmp = inside - inside = outside - outside = tmp - # 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: + self.safeHeight = float(PathUtil.opProperty(self.baseOp, 'SafeHeight')) + self.clearanceHeight = float(PathUtil.opProperty(self.baseOp, 'ClearanceHeight')) + self.strG1ZsafeHeight = Path.Command('G1', {'Z': self.safeHeight, 'F': tc.VertFeed.Value}) + self.strG0ZclearanceHeight = Path.Command('G0', {'Z': self.clearanceHeight}) + + cmd = self.baseOp.Path.Commands[0] + pos = cmd.Placement.Base # bogus m/c position to create first edge + bogusX = True + bogusY = True + commands = [cmd] + lastExit = None + for cmd in self.baseOp.Path.Commands[1:]: + if cmd.Name in PathGeom.CmdMoveAll: + if bogusX == True : + bogusX = ( 'X' not in cmd.Parameters ) + if bogusY : + bogusY = ( 'Y' not in cmd.Parameters ) + edge = PathGeom.edgeForCmd(cmd, pos) + if edge: + inside = edge.common(self.boundary).Edges + outside = edge.cut(self.boundary).Edges + if not self.inside: # UI "inside boundary" param + tmp = inside + inside = outside + outside = tmp + # 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: + if not ( bogusX or bogusY ) : # don't insert false paths based on bogus m/c position + commands.extend(self.boundaryCommands(lastExit, pos, tc.VertFeed.Value)) + 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] + LastPt = e.valueAt(e.LastParameter) + flip = PathGeom.pointsCoincide(pos, LastPt) + newPos = e.valueAt(e.FirstParameter) if flip else LastPt + # inside edges are taken at this point (see swap of inside/outside + # above - so we can just connect the dots ... + if lastExit: + if not ( bogusX or bogusY ) : commands.extend(self.boundaryCommands(lastExit, pos, tc.VertFeed.Value)) + lastExit = None + PathLog.track(e, flip) if not ( bogusX or bogusY ) : # don't insert false paths based on bogus m/c position - commands.extend(self.boundaryCommands(obj, lastExit, pos, tc.VertFeed.Value)) - 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] - LastPt = e.valueAt(e.LastParameter) - flip = PathGeom.pointsCoincide(pos, LastPt) - newPos = e.valueAt(e.FirstParameter) if flip else LastPt - # inside edges are taken at this point (see swap of inside/outside - # above - so we can just connect the dots ... - if lastExit: - if not ( bogusX or bogusY ) : commands.extend(self.boundaryCommands(obj, lastExit, pos, tc.VertFeed.Value)) - lastExit = None - PathLog.track(e, flip) - if not ( bogusX or bogusY ) : # don't insert false paths based on bogus m/c position - commands.extend(PathGeom.cmdsForEdge(e, flip, False, 50, tc.HorizFeed.Value, tc.VertFeed.Value)) - inside.remove(e) + commands.extend(PathGeom.cmdsForEdge(e, flip, False, 50, tc.HorizFeed.Value, tc.VertFeed.Value)) + 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/outside above) - so just move along ... + outside.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/outside 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') - # Eif + 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') # Eif - # Ewhile - # Eif - # pos = PathGeom.commandEndPoint(cmd, pos) + # Eif + # Ewhile # Eif - else: - PathLog.track('no-move', cmd) - commands.append(cmd) - if lastExit: - commands.extend(self.boundaryCommands(obj, lastExit, None, tc.VertFeed.Value)) - lastExit = None - else: - PathLog.warning("No Path Commands for %s" % obj.Base.Label) - commands = [] - PathLog.track(commands) - obj.Path = Path.Path(commands) + # pos = PathGeom.commandEndPoint(cmd, pos) + # Eif + else: + PathLog.track('no-move', cmd) + commands.append(cmd) + if lastExit: + commands.extend(self.boundaryCommands(lastExit, None, tc.VertFeed.Value)) + lastExit = None + PathLog.track(commands) + return Path.Path(commands) +# Eclass def Create(base, name='DressupPathBoundary'): '''Create(base, name='DressupPathBoundary') ... creates a dressup limiting base's Path to a boundary.''' diff --git a/src/Mod/Path/PathScripts/PathDrilling.py b/src/Mod/Path/PathScripts/PathDrilling.py index 907749a904..fbcbce910a 100644 --- a/src/Mod/Path/PathScripts/PathDrilling.py +++ b/src/Mod/Path/PathScripts/PathDrilling.py @@ -159,12 +159,13 @@ def SetupProperties(): setup.append("RetractHeight") return setup -def Create(name, obj = None): + +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Drilling operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectDrilling(obj, name) + obj.Proxy = ObjectDrilling(obj, name, parentJob) if obj.Proxy: obj.Proxy.findAllHoles(obj) diff --git a/src/Mod/Path/PathScripts/PathEngrave.py b/src/Mod/Path/PathScripts/PathEngrave.py index 0edba1b07a..b60d2c977e 100644 --- a/src/Mod/Path/PathScripts/PathEngrave.py +++ b/src/Mod/Path/PathScripts/PathEngrave.py @@ -48,8 +48,8 @@ def translate(context, text, disambig=None): class ObjectEngrave(PathEngraveBase.ObjectOp): '''Proxy class for Engrave operation.''' - def __init__(self, obj, name): - super(ObjectEngrave, self).__init__(obj, name) + def __init__(self, obj, name, parentJob): + super(ObjectEngrave, self).__init__(obj, name, parentJob) self.wires = [] def opFeatures(self, obj): @@ -144,9 +144,9 @@ def SetupProperties(): return ["StartVertex"] -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns an Engrave operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectEngrave(obj, name) + obj.Proxy = ObjectEngrave(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathHelix.py b/src/Mod/Path/PathScripts/PathHelix.py index 59a729ab84..b74669f53f 100644 --- a/src/Mod/Path/PathScripts/PathHelix.py +++ b/src/Mod/Path/PathScripts/PathHelix.py @@ -214,11 +214,11 @@ def SetupProperties(): return setup -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Helix operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectHelix(obj, name) + obj.Proxy = ObjectHelix(obj, name, parentJob) if obj.Proxy: obj.Proxy.findAllHoles(obj) return obj diff --git a/src/Mod/Path/PathScripts/PathJobGui.py b/src/Mod/Path/PathScripts/PathJobGui.py index ce62fd0923..327b676b30 100644 --- a/src/Mod/Path/PathScripts/PathJobGui.py +++ b/src/Mod/Path/PathScripts/PathJobGui.py @@ -175,8 +175,8 @@ class ViewProvider: FreeCADGui.Control.closeDialog() FreeCADGui.Control.showDialog(self.taskPanel) self.taskPanel.setupUi(activate) - self.deleteOnReject = False self.showOriginAxis(True) + self.deleteOnReject = False def resetTaskPanel(self): self.showOriginAxis(False) diff --git a/src/Mod/Path/PathScripts/PathMillFace.py b/src/Mod/Path/PathScripts/PathMillFace.py index db01c49379..f3c1d93511 100644 --- a/src/Mod/Path/PathScripts/PathMillFace.py +++ b/src/Mod/Path/PathScripts/PathMillFace.py @@ -304,9 +304,9 @@ def SetupProperties(): return setup -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Mill Facing operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectFace(obj, name) + obj.Proxy = ObjectFace(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathOp.py b/src/Mod/Path/PathScripts/PathOp.py index fa53a20093..d9537f99f7 100644 --- a/src/Mod/Path/PathScripts/PathOp.py +++ b/src/Mod/Path/PathScripts/PathOp.py @@ -119,7 +119,7 @@ class ObjectOp(object): obj.addProperty("App::PropertyDistance", "OpStockZMin", "Op Values", QtCore.QT_TRANSLATE_NOOP("PathOp", "Holds the min Z value of Stock")) obj.setEditorMode('OpStockZMin', 1) # read-only - def __init__(self, obj, name): + def __init__(self, obj, name, parentJob=None): PathLog.track() obj.addProperty("App::PropertyBool", "Active", "Path", QtCore.QT_TRANSLATE_NOOP("PathOp", "Make False, to prevent operation from generating code")) @@ -190,6 +190,8 @@ class ObjectOp(object): self.initOperation(obj) if not hasattr(obj, 'DoNotSetDefaultValues') or not obj.DoNotSetDefaultValues: + if parentJob: + self.job = PathUtils.addToJob(obj, jobname=parentJob.Name) job = self.setDefaultValues(obj) if job: job.SetupSheet.Proxy.setOperationProperties(obj, name) @@ -322,7 +324,10 @@ class ObjectOp(object): def setDefaultValues(self, obj): '''setDefaultValues(obj) ... base implementation. Do not overwrite, overwrite opSetDefaultValues() instead.''' - job = PathUtils.addToJob(obj) + if self.job: + job = self.job + else: + job = PathUtils.addToJob(obj) obj.Active = True @@ -622,5 +627,3 @@ class ObjectOp(object): This function can safely be overwritten by subclasses.''' return True - - diff --git a/src/Mod/Path/PathScripts/PathOpGui.py b/src/Mod/Path/PathScripts/PathOpGui.py index 33de983c24..0863fa9202 100644 --- a/src/Mod/Path/PathScripts/PathOpGui.py +++ b/src/Mod/Path/PathScripts/PathOpGui.py @@ -1287,12 +1287,12 @@ def Create(res): this function directly, but calls the Activated() function of the Command object that is created in each operations Gui implementation.''' FreeCAD.ActiveDocument.openTransaction("Create %s" % res.name) - obj = res.objFactory(res.name) + obj = res.objFactory(res.name, obj=None, parentJob=res.job) if obj.Proxy: obj.ViewObject.Proxy = ViewProvider(obj.ViewObject, res) obj.ViewObject.Visibility = False - FreeCAD.ActiveDocument.commitTransaction() + obj.ViewObject.Document.setEdit(obj.ViewObject, 0) return obj FreeCAD.ActiveDocument.abortTransaction() @@ -1336,6 +1336,7 @@ class CommandResources: self.menuText = menuText self.accelKey = accelKey self.toolTip = toolTip + self.job = None def SetupOperation(name, diff --git a/src/Mod/Path/PathScripts/PathPocket.py b/src/Mod/Path/PathScripts/PathPocket.py index 643cfdc06a..65249c6b20 100644 --- a/src/Mod/Path/PathScripts/PathPocket.py +++ b/src/Mod/Path/PathScripts/PathPocket.py @@ -717,9 +717,9 @@ def SetupProperties(): return PathPocketBase.SetupProperties() + ["HandleMultipleFeatures"] -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Pocket operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectPocket(obj, name) + obj.Proxy = ObjectPocket(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathPocketShape.py b/src/Mod/Path/PathScripts/PathPocketShape.py index a35326b9be..c57778be53 100644 --- a/src/Mod/Path/PathScripts/PathPocketShape.py +++ b/src/Mod/Path/PathScripts/PathPocketShape.py @@ -244,11 +244,11 @@ def SetupProperties(): return setup -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Pocket operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject('Path::FeaturePython', name) - - obj.Proxy = ObjectPocket(obj, name) + obj.Proxy = ObjectPocket(obj, name, parentJob) + return obj return obj \ No newline at end of file diff --git a/src/Mod/Path/PathScripts/PathProbe.py b/src/Mod/Path/PathScripts/PathProbe.py index f555b00075..e2fc33e8f0 100644 --- a/src/Mod/Path/PathScripts/PathProbe.py +++ b/src/Mod/Path/PathScripts/PathProbe.py @@ -97,9 +97,9 @@ def SetupProperties(): return setup -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Probing operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - proxy = ObjectProbing(obj, name) + proxy = ObjectProbing(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathProfile.py b/src/Mod/Path/PathScripts/PathProfile.py index 39f65f9956..07901949f8 100644 --- a/src/Mod/Path/PathScripts/PathProfile.py +++ b/src/Mod/Path/PathScripts/PathProfile.py @@ -1301,9 +1301,9 @@ def SetupProperties(): return setup -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Profile based on faces operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectProfile(obj, name) + obj.Proxy = ObjectProfile(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathProfileContour.py b/src/Mod/Path/PathScripts/PathProfileContour.py index e743cdc8eb..ba02016b48 100644 --- a/src/Mod/Path/PathScripts/PathProfileContour.py +++ b/src/Mod/Path/PathScripts/PathProfileContour.py @@ -42,9 +42,9 @@ def SetupProperties(): return PathProfile.SetupProperties() -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Profile operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectContour(obj, name) + obj.Proxy = ObjectContour(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathProfileEdges.py b/src/Mod/Path/PathScripts/PathProfileEdges.py index 26a28e701a..a79a93e2b1 100644 --- a/src/Mod/Path/PathScripts/PathProfileEdges.py +++ b/src/Mod/Path/PathScripts/PathProfileEdges.py @@ -43,9 +43,9 @@ def SetupProperties(): return PathProfile.SetupProperties() -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Profile operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectProfile(obj, name) + obj.Proxy = ObjectProfile(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathProfileFaces.py b/src/Mod/Path/PathScripts/PathProfileFaces.py index 2896ab4390..f8f0b705dc 100644 --- a/src/Mod/Path/PathScripts/PathProfileFaces.py +++ b/src/Mod/Path/PathScripts/PathProfileFaces.py @@ -44,9 +44,9 @@ def SetupProperties(): return PathProfile.SetupProperties() -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Profile operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectProfile(obj, name) + obj.Proxy = ObjectProfile(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathSetupSheet.py b/src/Mod/Path/PathScripts/PathSetupSheet.py index 9cdfb0596c..79fbc339c8 100644 --- a/src/Mod/Path/PathScripts/PathSetupSheet.py +++ b/src/Mod/Path/PathScripts/PathSetupSheet.py @@ -34,7 +34,7 @@ __doc__ = "A container for all default values and job specific configuration val _RegisteredOps = {} -PathLog.setLevel(PathLog.Level.DEBUG, PathLog.thisModule()) +PathLog.setLevel(PathLog.Level.INFO, PathLog.thisModule()) # PathLog.trackModule(PathLog.thisModule()) diff --git a/src/Mod/Path/PathScripts/PathSimulatorGui.py b/src/Mod/Path/PathScripts/PathSimulatorGui.py index 3a01944abc..9fc2344cbf 100644 --- a/src/Mod/Path/PathScripts/PathSimulatorGui.py +++ b/src/Mod/Path/PathScripts/PathSimulatorGui.py @@ -27,6 +27,7 @@ import PathScripts.PathDressup as PathDressup import PathScripts.PathGeom as PathGeom import PathScripts.PathLog as PathLog import PathScripts.PathUtil as PathUtil +import PathScripts.PathJob as PathJob import PathSimulator import math import os @@ -75,6 +76,7 @@ class PathSimulation: self.simperiod = 20 self.accuracy = 0.1 self.resetSimulation = False + self.jobs = [] def Connect(self, but, sig): QtCore.QObject.connect(but, QtCore.SIGNAL("clicked()"), sig) @@ -96,13 +98,9 @@ class PathSimulation: self.onSpeedBarChange() form.sliderAccuracy.valueChanged.connect(self.onAccuracyBarChange) self.onAccuracyBarChange() + self._populateJobSelection(form) form.comboJobs.currentIndexChanged.connect(self.onJobChange) - jobList = FreeCAD.ActiveDocument.findObjects("Path::FeaturePython", "Job.*") - form.comboJobs.clear() - self.jobs = [] - for j in jobList: - self.jobs.append(j) - form.comboJobs.addItem(j.ViewObject.Icon, j.Label) + self.onJobChange() FreeCADGui.Control.showDialog(self.taskForm) self.disableAnim = False self.isVoxel = True @@ -111,6 +109,40 @@ class PathSimulation: self.SimulateMill() self.initdone = True + def _populateJobSelection(self, form): + # Make Job selection combobox + setJobIdx = 0 + jobName = '' + jIdx = 0 + # Get list of Job objects in active document + jobList = FreeCAD.ActiveDocument.findObjects("Path::FeaturePython", "Job.*") + jCnt = len(jobList) + + # Check if user has selected a specific job for simulation + guiSelection = FreeCADGui.Selection.getSelectionEx() + if guiSelection: # Identify job selected by user + sel = guiSelection[0] + if hasattr(sel.Object, "Proxy") and isinstance(sel.Object.Proxy, PathJob.ObjectJob): + jobName = sel.Object.Name + FreeCADGui.Selection.clearSelection() + + # populate the job selection combobox + form.comboJobs.blockSignals(True) + form.comboJobs.clear() + form.comboJobs.blockSignals(False) + for j in jobList: + form.comboJobs.addItem(j.ViewObject.Icon, j.Label) + self.jobs.append(j) + if j.Name == jobName or jCnt == 1: + setJobIdx = jIdx + jIdx += 1 + + # Pre-select GUI-selected job in the combobox + if jobName or jCnt == 1: + form.comboJobs.setCurrentIndex(setJobIdx) + else: + form.comboJobs.setCurrentIndex(0) + def SetupSimulation(self): form = self.taskForm.form self.activeOps = [] diff --git a/src/Mod/Path/PathScripts/PathSlot.py b/src/Mod/Path/PathScripts/PathSlot.py index 472a7fbe8f..9048b66a08 100644 --- a/src/Mod/Path/PathScripts/PathSlot.py +++ b/src/Mod/Path/PathScripts/PathSlot.py @@ -1767,9 +1767,9 @@ def SetupProperties(): return [tup[1] for tup in ObjectSlot.opPropertyDefinitions(False)] -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Slot operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectSlot(obj, name) + obj.Proxy = ObjectSlot(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathSurface.py b/src/Mod/Path/PathScripts/PathSurface.py index 015fdbb579..bf2107b34c 100644 --- a/src/Mod/Path/PathScripts/PathSurface.py +++ b/src/Mod/Path/PathScripts/PathSurface.py @@ -2124,9 +2124,9 @@ def SetupProperties(): return [tup[1] for tup in ObjectSurface.opPropertyDefinitions(False)] -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Surface operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectSurface(obj, name) + obj.Proxy = ObjectSurface(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathThreadMilling.py b/src/Mod/Path/PathScripts/PathThreadMilling.py index f7ca04b19a..0c5580d8eb 100644 --- a/src/Mod/Path/PathScripts/PathThreadMilling.py +++ b/src/Mod/Path/PathScripts/PathThreadMilling.py @@ -327,11 +327,11 @@ def SetupProperties(): return setup -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a thread milling operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectThreadMilling(obj, name) + obj.Proxy = ObjectThreadMilling(obj, name, parentJob) if obj.Proxy: obj.Proxy.findAllHoles(obj) return obj diff --git a/src/Mod/Path/PathScripts/PathVcarve.py b/src/Mod/Path/PathScripts/PathVcarve.py index 4b93ed1ad3..45609ebcf3 100644 --- a/src/Mod/Path/PathScripts/PathVcarve.py +++ b/src/Mod/Path/PathScripts/PathVcarve.py @@ -363,9 +363,9 @@ def SetupProperties(): return ["Discretize"] -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Vcarve operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - ObjectVcarve(obj, name) + obj.Proxy = ObjectVcarve(obj, name, parentJob) return obj diff --git a/src/Mod/Path/PathScripts/PathWaterline.py b/src/Mod/Path/PathScripts/PathWaterline.py index 764d4c723b..9ccc95bd68 100644 --- a/src/Mod/Path/PathScripts/PathWaterline.py +++ b/src/Mod/Path/PathScripts/PathWaterline.py @@ -1814,9 +1814,9 @@ def SetupProperties(): return [tup[1] for tup in ObjectWaterline.opPropertyDefinitions(False)] -def Create(name, obj=None): +def Create(name, obj=None, parentJob=None): '''Create(name) ... Creates and returns a Waterline operation.''' if obj is None: obj = FreeCAD.ActiveDocument.addObject("Path::FeaturePython", name) - obj.Proxy = ObjectWaterline(obj, name) + obj.Proxy = ObjectWaterline(obj, name, parentJob) return obj