diff --git a/src/Mod/Path/Gui/Resources/panels/ContourEdit.ui b/src/Mod/Path/Gui/Resources/panels/ContourEdit.ui
index 5e18b18dec..2ce88aaeee 100644
--- a/src/Mod/Path/Gui/Resources/panels/ContourEdit.ui
+++ b/src/Mod/Path/Gui/Resources/panels/ContourEdit.ui
@@ -30,8 +30,8 @@
0
0
- 334
- 292
+ 108
+ 92
@@ -82,7 +82,7 @@
-
-
+
0.000000000000000
@@ -97,8 +97,8 @@
0
0
- 334
- 292
+ 141
+ 65
@@ -147,8 +147,8 @@
0
0
- 334
- 292
+ 336
+ 303
@@ -212,13 +212,6 @@
- -
-
-
- Use End Point
-
-
-
@@ -238,19 +231,9 @@
- -
-
-
- 0.000000000000000
-
-
- mm
-
-
-
-
-
+
0.000000000000000
@@ -258,13 +241,6 @@
- -
-
-
- Roll Radius
-
-
-
diff --git a/src/Mod/Path/InitGui.py b/src/Mod/Path/InitGui.py
index d375ecff65..f60387bb5c 100644
--- a/src/Mod/Path/InitGui.py
+++ b/src/Mod/Path/InitGui.py
@@ -140,7 +140,7 @@ class PathWorkbench (Workbench):
if "Profile" or "Contour" in FreeCADGui.Selection.getSelection()[0].Name:
#self.appendContextMenu("", ["Add_Tag"])
self.appendContextMenu("", ["Set_StartPoint"])
- self.appendContextMenu("", ["Set_EndPoint"])
+ #self.appendContextMenu("", ["Set_EndPoint"])
if "Remote" in FreeCADGui.Selection.getSelection()[0].Name:
self.appendContextMenu("", ["Refresh_Path"])
diff --git a/src/Mod/Path/PathScripts/PathContour.py b/src/Mod/Path/PathScripts/PathContour.py
index 863942c4bb..6b7b78790b 100644
--- a/src/Mod/Path/PathScripts/PathContour.py
+++ b/src/Mod/Path/PathScripts/PathContour.py
@@ -23,19 +23,19 @@
# ***************************************************************************
import FreeCAD
-from FreeCAD import Vector
+#from FreeCAD import Vector
import Path
import PathScripts.PathLog as PathLog
from PathScripts import PathUtils
from PathScripts.PathUtils import depth_params
from PySide import QtCore
-import TechDraw
+#import TechDraw
import ArchPanel
import Part
LOG_MODULE = 'PathContour'
PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
-#PathLog.trackModule('PathContour')
+PathLog.trackModule('PathContour')
if FreeCAD.GuiUp:
import FreeCADGui
@@ -80,14 +80,6 @@ class ObjectContour:
# 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"))
- obj.addProperty("App::PropertyLength", "ExtendAtStart", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "extra length of tool path before start of part edge"))
- obj.addProperty("App::PropertyLength", "LeadInLineLen", "Start Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "length of straight segment of toolpath that comes in at angle to first part edge"))
-
- # End Point Properties
- obj.addProperty("App::PropertyBool", "UseEndPoint", "End Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "make True, if specifying an End Point"))
- obj.addProperty("App::PropertyLength", "ExtendAtEnd", "End Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "extra length of tool path after end of part edge"))
- obj.addProperty("App::PropertyLength", "LeadOutLineLen", "End Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "length of straight segment of toolpath that comes in at angle to last part edge"))
- obj.addProperty("App::PropertyVector", "EndPoint", "End Point", QtCore.QT_TRANSLATE_NOOP("App::Property", "The end point of this path"))
# Contour Properties
obj.addProperty("App::PropertyEnumeration", "Direction", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "The direction that the toolpath should go around the part ClockWise CW or CounterClockWise CCW"))
@@ -97,7 +89,6 @@ class ObjectContour:
obj.Side = ['Left', 'Right', 'On'] # side of profile that cutter is on in relation to direction of profile
obj.setEditorMode('Side', 2) # hide
- obj.addProperty("App::PropertyDistance", "RollRadius", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "Radius at start and end"))
obj.addProperty("App::PropertyDistance", "OffsetExtra", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "Extra value to stay away from final Contour- good for roughing toolpath"))
obj.Proxy = self
@@ -132,100 +123,62 @@ class ObjectContour:
obj.ClearanceHeight = 10.0
obj.SafeHeight = 8.0
- def _buildPathArea(self, obj, edgelist, start = None):
+ def _buildPathArea(self, obj, baseobject, start=None):
+ PathLog.track()
- c = Part.Wire(edgelist)
- f = Part.makeFace([c], 'Part::FaceMakerSimple')
-
- profile = Path.Area(Offset=self.radius,SectionCount=1)
+ profile = Path.Area()
profile.setPlane(Part.makeCircle(10))
- profile.add(f)
- lshapes = [profile.getShape()]
+ profile.add(baseobject)
+
+ profileparams = {'Fill': 0,
+ 'Coplanar' : 0}
+
+ if obj.UseComp is False:
+ profileparams['Offset'] = 0.0
+ else:
+ profileparams['Offset'] = self.radius+obj.OffsetExtra.Value
+
+ profile.setParams(**profileparams)
+ PathLog.debug("About to profile with params: {}".format(profileparams))
depthparams = depth_params(
- clearance_height = obj.ClearanceHeight.Value,
- rapid_safety_space = 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)
+ clearance_height=obj.ClearanceHeight.Value,
+ rapid_safety_space=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)
- print (depthparams.get_depths())
- for l in depthparams.get_depths():
- c = lshapes[0].copy()
- c.Placement.Base.z = l
- lshapes.append(c)
+ sections = profile.makeSections(mode=0, project=True, heights=depthparams.get_depths())
+ shapelist = [sec.getShape() for sec in sections]
- if start is None:
- pp = Path.fromShapes(lshapes, verbose=False)
+ params = {'shapes': shapelist,
+ 'feedrate': self.horizFeed,
+ 'feedrate_v': self.vertFeed,
+ 'verbose': True,
+ 'resume_height': obj.StepDown.Value,
+ 'retraction': obj.ClearanceHeight.Value}
+
+ if obj.Direction == 'CCW':
+ params['orientation'] = 1
else:
- pp = Path.fromShapes(lshapes, start, verbose=False)
+ params['orientation'] = 0
+
+ if obj.UseStartPoint is True and obj.StartPoint is not None:
+ params['start'] = obj.StartPoint
+
+ PathLog.debug("Generating Path with params: {}".format(params))
+ pp = Path.fromShapes(**params)
+ PathLog.debug(pp)
+
return pp
-
- # def _buildPathLibarea(self, obj, edgelist):
- # import PathScripts.PathKurveUtils as PathKurveUtils
- # PathLog.track()
- # # import math
- # # import area
- # output = ""
- # if obj.Comment != "":
- # output += '(' + str(obj.Comment)+')\n'
-
- # if obj.StartPoint and obj.UseStartPoint:
- # startpoint = obj.StartPoint
- # else:
- # startpoint = None
-
- # if obj.EndPoint and obj.UseEndPoint:
- # endpoint = obj.EndPoint
- # else:
- # endpoint = None
-
- # PathKurveUtils.output('mem')
- # PathKurveUtils.feedrate_hv(self.horizFeed, self.vertFeed)
-
- # output = ""
- # output += "G0 Z" + str(obj.ClearanceHeight.Value) + "F " + PathUtils.fmt(self.vertRapid) + "\n"
- # curve = PathKurveUtils.makeAreaCurve(edgelist, obj.Direction, startpoint, endpoint)
-
- # roll_radius = 2.0
- # extend_at_start = 0.0
- # extend_at_end = 0.0
- # lead_in_line_len = 0.0
- # lead_out_line_len = 0 # obj.FinalDepth.Value, None)
-
- # PathKurveUtils.profile2(
-
- # if obj.UseComp is False:
- # obj.Side = 'On'
- # else:
- # if obj.Direction == 'CW':
- # obj.Side = 'Left'
- # else:
- # obj.Side = 'Right'
-
- # depthparams = depth_params(
- # obj.ClearanceHeight.Value,
- # obj.SafeHeight.Value, obj.StartDepth.Value, obj.StepDown.Value, 0.0,
- # obj.FinalDepth.Value, None)
-
- # PathKurveUtils.profile2(
- # curve, obj.Side, self.radius, self.vertFeed, self.horizFeed,
- # self.vertRapid, self.horizRapid, obj.OffsetExtra.Value, roll_radius,
- # None, None, depthparams, extend_at_start, extend_at_end,
- # lead_in_line_len, lead_out_line_len)
-
- # output += PathKurveUtils.retrieve_gcode()
- # return output
-
def execute(self, obj):
PathLog.track()
- import Part # math #DraftGeomUtils
- commandlist = []
- #output = ""
+ import Part
+ commandlist = []
toolLoad = obj.ToolController
if toolLoad is None or toolLoad.ToolNumber == 0:
@@ -236,23 +189,18 @@ class ObjectContour:
self.horizFeed = toolLoad.HorizFeed.Value
self.vertRapid = toolLoad.VertRapid.Value
self.horizRapid = toolLoad.HorizRapid.Value
- tool = toolLoad.Proxy.getTool(toolLoad) #PathUtils.getTool(obj, toolLoad.ToolNumber)
+ 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
- #self.radius = 0.25
else:
self.radius = tool.Diameter/2
- #output += "(" + obj.Label + ")"
commandlist.append(Path.Command("(" + obj.Label + ")"))
if not obj.UseComp:
- #output += "(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"
commandlist.append(Path.Command("(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"))
-
else:
- #output += "(Uncompensated Tool Path)"
commandlist.append(Path.Command("(Uncompensated Tool Path)"))
parentJob = PathUtils.findParentJob(obj)
@@ -269,34 +217,27 @@ class ObjectContour:
if isinstance(subobj.Proxy, ArchPanel.PanelCut):
shapes = baseobject.Proxy.getOutlines(baseobject, transform=True)
for shape in shapes:
- for wire in shape.Wires:
- edgelist = wire.Edges
- edgelist = Part.__sortEdges__(edgelist)
- PathLog.debug("Processing panel perimeter. edges found: {}".format(len(edgelist))) # subobj.Proxy.execute(subobj)
+ f = Part.makeFace([shape], 'Part::FaceMakerSimple')
+ thickness = baseobject.Group[0].Source.Thickness
+ contourshape = f.extrude(FreeCAD.Vector(0,0, thickness))
try:
- #output += self._buildPathLibarea(obj, edgelist)
- commandlist.extend(self._buildPathArea(obj, edgelist).Commands)
- except Exception as e:
- print(e)
+ commandlist.extend(self._buildPathArea(obj, contourshape).Commands)
+ except Exception as e:
+ print(e)
FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
else:
- fixbase = baseobject.Shape.copy()
- fixbase.fix(0.00001,0.00001,0.00001)
- contourwire = TechDraw.findShapeOutline(fixbase, 1, Vector(0, 0, 1))
-
- edgelist = contourwire.Edges
- edgelist = Part.__sortEdges__(edgelist)
+ #fixbase = baseobject.Shape.copy()
+ #fixbase.fix(0.00001, 0.00001, 0.00001)
+ env = PathUtils.getEnvelope(baseobject.Shape, obj.StartDepth)
try:
- commandlist.extend(self._buildPathArea(obj, edgelist).Commands)
- except Exception as e:
- print(e)
+ commandlist.extend(self._buildPathArea(obj, env).Commands)
+ except Exception as e:
+ print(e)
FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
+
if obj.Active:
path = Path.Path(commandlist)
- # for c in contourcommands.Commands:
- # path.addCommands(c)
-
obj.Path = path
if obj.ViewObject:
obj.ViewObject.Visibility = True
@@ -348,26 +289,6 @@ class _CommandSetStartPoint:
obj.StartPoint.y = point.y
def Activated(self):
-
- FreeCADGui.Snapper.getPoint(callback=self.setpoint)
-
-
-class _CommandSetEndPoint:
- def GetResources(self):
- return {'Pixmap': 'Path-EndPoint',
- 'MenuText': QtCore.QT_TRANSLATE_NOOP("Path_Contour", "Pick End Point"),
- 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Path_Contour", "Pick End Point")}
-
- def IsActive(self):
- return FreeCAD.ActiveDocument is not None
-
- def setpoint(self, point, o):
- obj = FreeCADGui.Selection.getSelection()[0]
- obj.EndPoint.x = point.x
- obj.EndPoint.y = point.y
-
- def Activated(self):
-
FreeCADGui.Snapper.getPoint(callback=self.setpoint)
@@ -450,14 +371,10 @@ class TaskPanel:
self.obj.StepDown = FreeCAD.Units.Quantity(self.form.stepDown.text()).Value
if hasattr(self.obj, "OffsetExtra"):
self.obj.OffsetExtra = FreeCAD.Units.Quantity(self.form.extraOffset.text()).Value
- if hasattr(self.obj, "RollRadius"):
- self.obj.RollRadius = FreeCAD.Units.Quantity(self.form.rollRadius.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, "UseEndPoint"):
- self.obj.UseEndPoint = self.form.useEndPoint.isChecked()
if hasattr(self.obj, "Direction"):
self.obj.Direction = str(self.form.direction.currentText())
if hasattr(self.obj, "ToolController"):
@@ -473,10 +390,8 @@ class TaskPanel:
self.form.clearanceHeight.setText(FreeCAD.Units.Quantity(self.obj.ClearanceHeight.Value, FreeCAD.Units.Length).UserString)
self.form.stepDown.setText(FreeCAD.Units.Quantity(self.obj.StepDown.Value, FreeCAD.Units.Length).UserString)
self.form.extraOffset.setText(FreeCAD.Units.Quantity(self.obj.OffsetExtra.Value, FreeCAD.Units.Length).UserString)
- self.form.rollRadius.setText(FreeCAD.Units.Quantity(self.obj.RollRadius.Value, FreeCAD.Units.Length).UserString)
self.form.useCompensation.setChecked(self.obj.UseComp)
self.form.useStartPoint.setChecked(self.obj.UseStartPoint)
- self.form.useEndPoint.setChecked(self.obj.UseEndPoint)
index = self.form.direction.findText(
self.obj.Direction, QtCore.Qt.MatchFixedString)
@@ -529,9 +444,7 @@ class TaskPanel:
self.form.uiToolController.currentIndexChanged.connect(self.getFields)
self.form.useCompensation.clicked.connect(self.getFields)
self.form.useStartPoint.clicked.connect(self.getFields)
- self.form.useEndPoint.clicked.connect(self.getFields)
self.form.extraOffset.editingFinished.connect(self.getFields)
- self.form.rollRadius.editingFinished.connect(self.getFields)
self.setFields()
@@ -554,6 +467,5 @@ if FreeCAD.GuiUp:
# register the FreeCAD command
FreeCADGui.addCommand('Path_Contour', CommandPathContour())
FreeCADGui.addCommand('Set_StartPoint', _CommandSetStartPoint())
- FreeCADGui.addCommand('Set_EndPoint', _CommandSetEndPoint())
FreeCAD.Console.PrintLog("Loading PathContour... done\n")
diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py
index fd6aab8be4..10f4d05d9c 100644
--- a/src/Mod/Path/PathScripts/PathUtils.py
+++ b/src/Mod/Path/PathScripts/PathUtils.py
@@ -33,6 +33,7 @@ import numpy
import PathLog
#from math import pi
from FreeCAD import Vector
+import Path
LOG_MODULE = 'PathUtils'
PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
@@ -193,6 +194,22 @@ def filterArcs(arcEdge):
pass
return splitlist
+def getEnvelope(partshape, stockheight=None):
+ '''
+ getEnvelop(partshape, stockheight=None)
+ returns a shape corresponding to the partshape silhouette extruded to height.
+ if stockheight is given, the returned shape is extruded to that height otherwise the returned shape
+ is the height of the original shape boundbox
+ partshape = solid object
+ stockheight = float
+ '''
+ area = Path.Area(Fill=1, Coplanar=0).add(partshape)
+ area.setPlane(Part.makeCircle(10))
+ sec = area.makeSections(heights=[1.0], project=True)[0].getShape(rebuild=True)
+ if stockheight is not None:
+ return sec.extrude(FreeCAD.Vector(0, 0, stockheight))
+ else:
+ return sec.extrude(FreeCAD.Vector(0, 0, partshape.BoundBox.ZMax))
def reverseEdge(e):
if geomType(e) == "Circle":