diff --git a/src/Mod/Path/Gui/Resources/panels/ProfileEdit.ui b/src/Mod/Path/Gui/Resources/panels/ProfileEdit.ui
index 5964a1104e..29a8b48385 100644
--- a/src/Mod/Path/Gui/Resources/panels/ProfileEdit.ui
+++ b/src/Mod/Path/Gui/Resources/panels/ProfileEdit.ui
@@ -33,8 +33,8 @@
0
0
- 381
- 381
+ 285
+ 277
@@ -111,8 +111,8 @@
0
0
- 381
- 381
+ 120
+ 96
@@ -178,8 +178,8 @@
0
0
- 381
- 381
+ 154
+ 68
@@ -343,13 +343,6 @@
- -
-
-
- Roll Radius
-
-
-
-
@@ -360,16 +353,6 @@
- -
-
-
- 0.000000000000000
-
-
- mm
-
-
-
@@ -390,13 +373,6 @@
- -
-
-
- Use End Point
-
-
-
-
diff --git a/src/Mod/Path/PathScripts/PathContour.py b/src/Mod/Path/PathScripts/PathContour.py
index 34f2e48d4a..3c1ab1870d 100644
--- a/src/Mod/Path/PathScripts/PathContour.py
+++ b/src/Mod/Path/PathScripts/PathContour.py
@@ -34,8 +34,8 @@ from PathScripts.PathUtils import waiting_effects
from PathScripts.PathUtils import makeWorkplane
LOG_MODULE = 'PathContour'
-PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
-#PathLog.trackModule('PathContour')
+PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE)
+PathLog.trackModule('PathContour')
FreeCAD.setLogLevel('Path.Area', 0)
if FreeCAD.GuiUp:
@@ -77,9 +77,9 @@ class ObjectContour:
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"))
obj.Direction = ['CW', 'CCW'] # this is the direction that the Contour runs
obj.addProperty("App::PropertyBool", "UseComp", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "make True, if using Cutter Radius Compensation"))
- obj.addProperty("App::PropertyEnumeration", "Side", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "Side of edge that tool should cut"))
- 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::PropertyEnumeration", "Side", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "Side of edge that tool should cut"))
+ # obj.Side = ['Left', 'Right'] # side of profile that cutter is on in relation to direction of profile
+ # obj.setEditorMode('Side', 2) # hide
obj.addProperty("App::PropertyDistance", "OffsetExtra", "Contour", QtCore.QT_TRANSLATE_NOOP("App::Property", "Extra value to stay away from final Contour- good for roughing toolpath"))
@@ -94,8 +94,11 @@ class ObjectContour:
def onChanged(self, obj, prop):
pass
- # if prop in ['ClearanceHeight', 'StartPoint']:
- # obj.StartPoint.z = obj.ClearanceHeight.Value
+ # if prop == "UseComp":
+ # if not obj.UseComp:
+ # obj.setEditorMode('Side', 2)
+ # else:
+ # obj.setEditorMode('Side', 0)
def setDepths(proxy, obj):
PathLog.track()
@@ -171,22 +174,22 @@ class ObjectContour:
PathLog.debug('pp: {}, end vector: {}'.format(pp, end_vector))
self.endVector = end_vector
- if True:
- from PathScripts.PathUtils import CollisionTester
- parentJob = PathUtils.findParentJob(obj)
- if parentJob is None:
- pass
- base = parentJob.Base
- if base is None:
- pass
+# if True:
+# from PathScripts.PathUtils import CollisionTester
+# parentJob = PathUtils.findParentJob(obj)
+# if parentJob is None:
+# pass
+# base = parentJob.Base
+# if base is None:
+# pass
- profileparams['Thicken'] = True #{'Fill':0, 'Coplanar':0, 'Project':True, 'SectionMode':2, 'Thicken':True}
- profileparams['ToolRadius']= self.radius - self.radius *.005
- profile.setParams(**profileparams)
- sec = profile.makeSections(heights=[0.0])[0].getShape()
- cutPath = sec.extrude(FreeCAD.Vector(0,0,baseobject.BoundBox.ZMax))
- c = CollisionTester()
- c.getCollisionSim(base.Shape, cutPath)
+# profileparams['Thicken'] = True #{'Fill':0, 'Coplanar':0, 'Project':True, 'SectionMode':2, 'Thicken':True}
+# profileparams['ToolRadius']= self.radius - self.radius *.005
+# profile.setParams(**profileparams)
+# sec = profile.makeSections(heights=[0.0])[0].getShape()
+# cutPath = sec.extrude(FreeCAD.Vector(0,0,baseobject.BoundBox.ZMax))
+# c = CollisionTester()
+# c.getCollisionSim(base.Shape, cutPath)
return pp
@@ -194,6 +197,12 @@ class ObjectContour:
PathLog.track()
self.endVector = None
+ if not obj.Active:
+ path = Path.Path("(inactive operation)")
+ obj.Path = path
+ obj.ViewObject.Visibility = False
+ return
+
commandlist = []
toolLoad = obj.ToolController
@@ -244,22 +253,16 @@ class ObjectContour:
FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
else:
bb = baseobject.Shape.BoundBox
- env = PathUtils.getEnvelope(partshape=baseobject.Shape, stockheight=bb.ZLength + (obj.StartDepth.Value-bb.ZMax))
+ env = PathUtils.getEnvelope(partshape=baseobject.Shape, subshape=None, stockheight=bb.ZLength + (obj.StartDepth.Value-bb.ZMax))
try:
commandlist.extend(self._buildPathArea(obj, env, start=obj.StartPoint).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)
- obj.Path = path
- if obj.ViewObject:
- obj.ViewObject.Visibility = True
- else:
- path = Path.Path("(inactive operation)")
- obj.Path = path
- obj.ViewObject.Visibility = False
+ path = Path.Path(commandlist)
+ obj.Path = path
+ obj.ViewObject.Visibility = True
class _ViewProviderContour:
diff --git a/src/Mod/Path/PathScripts/PathMillFace.py b/src/Mod/Path/PathScripts/PathMillFace.py
index b221dd2a46..8c224aeb1c 100644
--- a/src/Mod/Path/PathScripts/PathMillFace.py
+++ b/src/Mod/Path/PathScripts/PathMillFace.py
@@ -226,6 +226,12 @@ class ObjectFace:
def execute(self, obj):
PathLog.track()
+ if not obj.Active:
+ path = Path.Path("(inactive operation)")
+ obj.Path = path
+ obj.ViewObject.Visibility = False
+ return
+
commandlist = []
toolLoad = obj.ToolController
@@ -288,18 +294,12 @@ class ObjectFace:
try:
commandlist.extend(self._buildPathArea(obj, env).Commands)
except Exception as e:
- print(e)
- FreeCAD.Console.PrintWarning(translate("Path_MillFace", "The selected settings did not produce a valid path.\n"))
+ FreeCAD.Console.PrintError(e)
+ FreeCAD.Console.PrintError(translate("Path_MillFace", "The selected settings did not produce a valid path.\n"))
- if obj.Active:
- path = Path.Path(commandlist)
- obj.Path = path
- if obj.ViewObject:
- obj.ViewObject.Visibility = True
- else:
- path = Path.Path("(inactive operation)")
- obj.Path = path
- obj.ViewObject.Visibility = False
+ path = Path.Path(commandlist)
+ obj.Path = path
+ obj.ViewObject.Visibility = True
class _CommandSetFaceStartPoint:
diff --git a/src/Mod/Path/PathScripts/PathPocket.py b/src/Mod/Path/PathScripts/PathPocket.py
index c34a8c2c97..358bec96bc 100644
--- a/src/Mod/Path/PathScripts/PathPocket.py
+++ b/src/Mod/Path/PathScripts/PathPocket.py
@@ -37,14 +37,16 @@ if FreeCAD.GuiUp:
"""Path Pocket object and FreeCAD command"""
LOG_MODULE = 'PathPocket'
-PathLog.setLevel(PathLog.Level.DEBUG, LOG_MODULE)
-PathLog.trackModule('PathPocket')
-FreeCAD.setLogLevel('Path.Area',0)
+PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
+#PathLog.trackModule('PathPocket')
+FreeCAD.setLogLevel('Path.Area', 0)
+
# Qt tanslation handling
def translate(context, text, disambig=None):
return QtCore.QCoreApplication.translate(context, text, disambig)
+
class ObjectPocket:
def __init__(self, obj):
@@ -75,7 +77,6 @@ class ObjectPocket:
obj.addProperty("App::PropertyEnumeration", "OffsetPattern", "Face", QtCore.QT_TRANSLATE_NOOP("App::Property", "clearing pattern to use"))
obj.OffsetPattern = ['ZigZag', 'Offset', 'Spiral', 'ZigZagOffset', 'Line', 'Grid', 'Triangle']
-
# 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"))
@@ -163,11 +164,11 @@ class ObjectPocket:
return None
@waiting_effects
- def _buildPathArea(self, obj, baseobject):
+ def _buildPathArea(self, obj, envelopeshape):
PathLog.track()
pocket = Path.Area()
pocket.setPlane(Part.makeCircle(10))
- pocket.add(baseobject)
+ pocket.add(envelopeshape)
stepover = (self.radius * 2) * (float(obj.StepOver)/100)
@@ -205,16 +206,11 @@ class ObjectPocket:
'resume_height': obj.StepDown.Value,
'retraction': obj.ClearanceHeight.Value}
-
- # if obj.UseStartPoint is True and obj.StartPoint is not None:
- # params['start'] = obj.StartPoint
-
pp = Path.fromShapes(**params)
PathLog.debug("Generating Path with params: {}".format(params))
PathLog.debug(pp)
return pp
-
def execute(self, obj):
PathLog.track()
commandlist = []
@@ -225,6 +221,13 @@ class ObjectPocket:
obj.ViewObject.Visibility = False
return
+ parentJob = PathUtils.findParentJob(obj)
+ if parentJob is None:
+ return
+ baseobject = parentJob.Base
+ if baseobject is None:
+ return
+
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.")
@@ -251,25 +254,20 @@ class ObjectPocket:
edges = [getattr(b[0].Shape, sub) for sub in b[1]]
shape = Part.makeFace(edges, 'Part::FaceMakerSimple')
- env = PathUtils.getEnvelope(shape, obj.StartDepth)
+ env = PathUtils.getEnvelope(baseobject.Shape, subshape=shape, stockheight=obj.StartDepth)
try:
- commandlist.extend(self._buildPathArea(obj, env.cut(b[0].Shape)).Commands)
+ commandlist.extend(self._buildPathArea(obj, env.cut(baseobject.Shape)).Commands)
except Exception as e:
- print(e)
+ FreeCAD.Console.PrintError(e)
FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a pocket path. Check project and tool config.")
else: # process the job base object as a whole
PathLog.debug("processing the whole job base object")
- parentJob = PathUtils.findParentJob(obj)
- if parentJob is None:
- return
- baseobject = parentJob.Base
- if baseobject is None:
- return
- env = PathUtils.getEnvelope(baseobject.Shape, obj.StartDepth)
+
+ env = PathUtils.getEnvelope(baseobject.Shape, subshape=None, stockheight=obj.StartDepth)
try:
commandlist.extend(self._buildPathArea(obj, env.cut(baseobject.Shape)).Commands)
except Exception as e:
- print(e)
+ FreeCAD.Console.PrintError(e)
FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a pocket path. Check project and tool config.")
path = Path.Path(commandlist)
@@ -362,7 +360,7 @@ class CommandPathPocket:
FreeCADGui.doCommand('obj.ToolController = PathScripts.PathUtils.findToolController(obj)')
FreeCAD.ActiveDocument.commitTransaction()
- #FreeCAD.ActiveDocument.recompute()
+ # FreeCAD.ActiveDocument.recompute()
FreeCADGui.doCommand('obj.ViewObject.startEditing()')
@@ -403,6 +401,8 @@ class TaskPanel:
self.obj.UseStartPoint = self.form.useStartPoint.isChecked()
if hasattr(self.obj, "CutMode"):
self.obj.CutMode = str(self.form.cutMode.currentText())
+ if hasattr(self.obj, "OffsetPattern"):
+ self.obj.OffsetPattern = str(self.form.offsetpattern.currentText())
if hasattr(self.obj, "ZigZagAngle"):
self.obj.ZigZagAngle = FreeCAD.Units.Quantity(self.form.zigZagAngle.text()).Value
if hasattr(self.obj, "StepOver"):
@@ -425,11 +425,12 @@ class TaskPanel:
self.form.zigZagAngle.setText(FreeCAD.Units.Quantity(self.obj.ZigZagAngle, FreeCAD.Units.Angle).UserString)
self.form.stepOverPercent.setValue(self.obj.StepOver)
- # index = self.form.algorithmSelect.findText(self.obj.Algorithm, QtCore.Qt.MatchFixedString)
- # if index >= 0:
- # self.form.algorithmSelect.blockSignals(True)
- # self.form.algorithmSelect.setCurrentIndex(index)
- # self.form.algorithmSelect.blockSignals(False)
+ index = self.form.offsetpattern.findText(
+ self.obj.OffsetPattern, QtCore.Qt.MatchFixedString)
+ if index >= 0:
+ self.form.offsetpattern.blockSignals(True)
+ self.form.offsetpattern.setCurrentIndex(index)
+ self.form.offsetpattern.blockSignals(False)
index = self.form.cutMode.findText(
self.obj.CutMode, QtCore.Qt.MatchFixedString)
diff --git a/src/Mod/Path/PathScripts/PathProfile.py b/src/Mod/Path/PathScripts/PathProfile.py
index 4b2b7f0fd4..215264e2ba 100644
--- a/src/Mod/Path/PathScripts/PathProfile.py
+++ b/src/Mod/Path/PathScripts/PathProfile.py
@@ -34,7 +34,7 @@ import PathScripts.PathLog as PathLog
LOG_MODULE = 'PathProfile'
PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
-# PathLog.trackModule('PathProfile')
+PathLog.trackModule('PathProfile')
FreeCAD.setLogLevel('Path.Area', 0)
if FreeCAD.GuiUp:
@@ -76,7 +76,7 @@ class ObjectProfile:
# Profile Properties
obj.addProperty("App::PropertyEnumeration", "Side", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property", "Side of edge that tool should cut"))
- obj.Side = ['Left', 'Right', 'On'] # side of profile that cutter is on in relation to direction of profile
+ obj.Side = ['Left', 'Right'] # side of profile that cutter is on in relation to direction of profile
obj.addProperty("App::PropertyEnumeration", "Direction", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property", "The direction that the toolpath should go around the part ClockWise CW or CounterClockWise CCW"))
obj.Direction = ['CW', 'CCW'] # this is the direction that the profile runs
obj.addProperty("App::PropertyBool", "UseComp", "Profile", QtCore.QT_TRANSLATE_NOOP("App::Property", "make True, if using Cutter Radius Compensation"))
@@ -94,7 +94,11 @@ class ObjectProfile:
return None
def onChanged(self, obj, prop):
- pass
+ if prop == "UseComp":
+ if not obj.UseComp:
+ obj.setEditorMode('Side', 2)
+ else:
+ obj.setEditorMode('Side', 0)
def addprofilebase(self, obj, ss, sub=""):
baselist = obj.Base
@@ -135,22 +139,29 @@ class ObjectProfile:
obj.Base = baselist
self.execute(obj)
- def _buildPathArea(self, obj, baseobject, isHole, start=None):
+ def _buildPathArea(self, obj, baseobject, isHole=False, start=None):
PathLog.track()
profile = Path.Area()
profile.setPlane(Part.makeCircle(10))
profile.add(baseobject)
profileparams = {'Fill': 0,
- 'Coplanar': 0,
+ 'Coplanar': 2,
'Offset': 0.0,
'SectionCount': -1}
+ offsetval = 0
+
if obj.UseComp:
- if isHole:
- profileparams['Offset'] = 0 - self.radius+obj.OffsetExtra.Value
- else:
- profileparams['Offset'] = self.radius+obj.OffsetExtra.Value
+ offsetval = self.radius+obj.OffsetExtra.Value
+
+ if obj.Side == 'Right':
+ offsetval = 0 - offsetval
+
+ if isHole:
+ offsetval = 0 - offsetval
+
+ profileparams['Offset'] = offsetval
profile.setParams(**profileparams)
# PathLog.debug("About to profile with params: {}".format(profileparams))
@@ -175,7 +186,7 @@ class ObjectProfile:
'resume_height': obj.StepDown.Value,
'retraction': obj.ClearanceHeight.Value}
- # Reverse the direction for holes
+ #Reverse the direction for holes
if isHole:
direction = "CW" if obj.Direction == "CCW" else "CCW"
else:
@@ -197,8 +208,14 @@ class ObjectProfile:
def execute(self, obj):
import Part
- commandlist = []
+ if not obj.Active:
+ path = Path.Path("(inactive operation)")
+ obj.Path = path
+ obj.ViewObject.Visibility = False
+ return
+
+ 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.")
@@ -222,7 +239,14 @@ class ObjectProfile:
else:
commandlist.append(Path.Command("(Uncompensated Tool Path)"))
- if obj.Base:
+ parentJob = PathUtils.findParentJob(obj)
+ if parentJob is None:
+ return
+ baseobject = parentJob.Base
+ if baseobject is None:
+ return
+
+ if obj.Base: # The user has selected subobjects from the base. Process each.
holes = []
faces = []
for b in obj.Base:
@@ -233,46 +257,34 @@ class ObjectProfile:
if numpy.isclose(abs(shape.normalAt(0, 0).z), 1): # horizontal face
holes += shape.Wires[1:]
else:
- print ("found a base object which is not a face. Can't continue.")
+ FreeCAD.Console.PrintWarning ("found a base object which is not a face. Can't continue.")
return
if obj.processHoles:
for wire in holes:
f = Part.makeFace(wire, 'Part::FaceMakerSimple')
+ drillable = PathUtils.isDrillable(baseobject.Shape, wire)
+ if (drillable and obj.processCircles) or (not drillable and obj.processHoles):
- # shift the compound to the bottom of the base object for
- # proper sectioning
- zShift = b[0].Shape.BoundBox.ZMin - f.BoundBox.ZMin
- newPlace = FreeCAD.Placement(FreeCAD.Vector(0, 0, zShift), f.Placement.Rotation)
- f.Placement = newPlace
- env = PathUtils.getEnvelope(f, obj.StartDepth)
- try:
- commandlist.extend(self._buildPathArea(obj, baseobject=env, isHole=True, start=None).Commands)
- except Exception as e:
- print(e)
- FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
+ env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, stockheight=obj.StartDepth)
+ try:
+ commandlist.extend(self._buildPathArea(obj, baseobject=env, isHole=True, start=None).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.")
- profileshape = Part.makeCompound(faces)
- zShift = b[0].Shape.BoundBox.ZMin - profileshape.BoundBox.ZMin
- newPlace = FreeCAD.Placement(FreeCAD.Vector(0, 0, zShift), profileshape.Placement.Rotation)
- profileshape.Placement = newPlace
+ if len(faces) > 0:
+ profileshape = Part.makeCompound(faces)
if obj.processPerimeter:
- env = PathUtils.getEnvelope(profileshape, obj.StartDepth)
+ env = PathUtils.getEnvelope(baseobject.Shape, subshape=profileshape, stockheight=obj.StartDepth)
try:
- commandlist.extend(self._buildPathArea(obj, baseobject=env, isHole=False, start=None).Commands)
+ commandlist.extend(self._buildPathArea(obj, baseobject=env, start=None).Commands)
except Exception as e:
- print(e)
+ FreeCAD.Console.PrintError(e)
FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
- else: # Try to build targets frorm the job base
- parentJob = PathUtils.findParentJob(obj)
- if parentJob is None:
- return
- baseobject = parentJob.Base
- if baseobject is None:
- return
-
+ else: # Try to build targets from the job base
if hasattr(baseobject, "Proxy"):
if isinstance(baseobject.Proxy, ArchPanel.PanelSheet): # process the sheet
if obj.processPerimeter:
@@ -280,11 +292,11 @@ class ObjectProfile:
for shape in shapes:
for wire in shape.Wires:
f = Part.makeFace(wire, 'Part::FaceMakerSimple')
- env = PathUtils.getEnvelope(f, obj.StartDepth)
+ env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, stockheight=obj.StartDepth)
try:
commandlist.extend(self._buildPathArea(obj, baseobject=env, isHole=False, start=None).Commands)
except Exception as e:
- print(e)
+ FreeCAD.Console.PrintError(e)
FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
shapes = baseobject.Proxy.getHoles(baseobject, transform=True)
@@ -293,22 +305,16 @@ class ObjectProfile:
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(f, obj.StartDepth)
+ env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, stockheight=obj.StartDepth)
try:
commandlist.extend(self._buildPathArea(obj, baseobject=env, isHole=True, start=None).Commands)
except Exception as e:
- print(e)
+ FreeCAD.Console.PrintError(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)
- obj.Path = path
- obj.ViewObject.Visibility = True
-
- else:
- path = Path.Path("(inactive operation)")
- obj.Path = path
- obj.ViewObject.Visibility = False
+ path = Path.Path(commandlist)
+ obj.Path = path
+ obj.ViewObject.Visibility = True
class _ViewProviderProfile:
diff --git a/src/Mod/Path/PathScripts/PathProfileEdges.py b/src/Mod/Path/PathScripts/PathProfileEdges.py
index 4add9e0148..f58d502913 100644
--- a/src/Mod/Path/PathScripts/PathProfileEdges.py
+++ b/src/Mod/Path/PathScripts/PathProfileEdges.py
@@ -28,6 +28,7 @@ import Part
from PathScripts import PathUtils
from PathScripts.PathUtils import depth_params
from DraftGeomUtils import findWires
+from DraftGeomUtils import isReallyClosed
import PathScripts.PathLog as PathLog
from PathScripts.PathUtils import waiting_effects
@@ -92,7 +93,11 @@ class ObjectProfile:
return None
def onChanged(self, obj, prop):
- pass
+ if prop == "UseComp":
+ if not obj.UseComp:
+ obj.setEditorMode('Side', 2)
+ else:
+ obj.setEditorMode('Side', 0)
def addprofilebase(self, obj, ss, sub=""):
baselist = obj.Base
@@ -218,6 +223,12 @@ class ObjectProfile:
obj.ViewObject.Visibility = False
return
+ parentJob = PathUtils.findParentJob(obj)
+ if parentJob is None:
+ return
+ baseobject = parentJob.Base
+ if baseobject is None:
+ return
toolLoad = obj.ToolController
if toolLoad is None or toolLoad.ToolNumber == 0:
@@ -235,12 +246,12 @@ class ObjectProfile:
self.radius = tool.Diameter/2
commandlist.append(Path.Command("(" + obj.Label + ")"))
-
+
if obj.UseComp:
commandlist.append(Path.Command("(Compensated Tool Path. Diameter: " + str(self.radius * 2) + ")"))
else:
commandlist.append(Path.Command("(Uncompensated Tool Path)"))
-
+
if obj.Base:
wires = []
@@ -258,14 +269,14 @@ class ObjectProfile:
zShift = b[0].Shape.BoundBox.ZMin - f.BoundBox.ZMin
newPlace = FreeCAD.Placement(FreeCAD.Vector(0, 0, zShift), f.Placement.Rotation)
f.Placement = newPlace
- env = PathUtils.getEnvelope(f, obj.StartDepth)
+ env = PathUtils.getEnvelope(baseobject.Shape, subshape=f, stockheight=obj.StartDepth)
try:
# commandlist.extend(self._buildPathArea(obj, wire).Commands)
commandlist.extend(self._buildPathArea(obj, baseobject=env, start=None).Commands)
-
+
except Exception as e:
- print(e)
+ FreeCAD.Console.PrintError(e)
FreeCAD.Console.PrintError("Something unexpected happened. Unable to generate a contour path. Check project and tool config.")
path = Path.Path(commandlist)
@@ -492,6 +503,14 @@ class TaskPanel:
if not selection[0].SubObjects[0].ShapeType == "Edge":
FreeCAD.Console.PrintError(translate("PathProject", "Please select one or more edges from the Base model\n"))
return
+ try:
+ theWire = Part.Wire(sel.SubObjects)
+ except:
+ FreeCAD.Console.PrintError(translate("PathProject", "The selected edges don't form a closed loop\n"))
+ return
+ if not isReallyClosed(theWire):
+ FreeCAD.Console.PrintError(translate("PathProject", "The selected edges don't form a closed loop\n"))
+ return
for i in sel.SubElementNames:
self.obj.Proxy.addprofilebase(self.obj, sel.Object, i)
diff --git a/src/Mod/Path/PathScripts/PathUtils.py b/src/Mod/Path/PathScripts/PathUtils.py
index 54b8e5cb1f..7325da3573 100644
--- a/src/Mod/Path/PathScripts/PathUtils.py
+++ b/src/Mod/Path/PathScripts/PathUtils.py
@@ -38,7 +38,7 @@ from PySide import QtGui
LOG_MODULE = 'PathUtils'
PathLog.setLevel(PathLog.Level.INFO, LOG_MODULE)
-PathLog.trackModule('PathUtils')
+#PathLog.trackModule('PathUtils')
FreeCAD.setLogLevel('Path.Area', 0)
def waiting_effects(function):
@@ -236,34 +236,51 @@ def makeWorkplane(shape):
return c
-def getEnvelope(partshape, stockheight=None):
+def getEnvelope(partshape, subshape=None, stockheight=None):
'''
- getEnvelop(partshape, stockheight=None)
+ getEnvelope(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
+ stockheight = float - Absolute Z height of the top of material before cutting.
'''
- PathLog.track(partshape, stockheight)
- area = Path.Area(Fill=1, Coplanar=0).add(partshape)
- # loc = FreeCAD.Vector(partshape.BoundBox.Center.x,
- # partshape.BoundBox.Center.y,
- # partshape.BoundBox.ZMin)
- area.setPlane(makeWorkplane(partshape))
- sec = area.makeSections(heights=[1.0], project=True)[0].getShape()
+ PathLog.track(partshape, subshape, stockheight)
+
+ # if partshape.Volume == 0.0: #Not a 3D object
+ # return None
+
+ if subshape is not None:
+ if isinstance(subshape, Part.Face):
+ PathLog.debug('processing a face')
+ sec = Part.makeCompound([subshape])
+ else:
+ area = Path.Area(Fill=2, Coplanar=0).add(subshape)
+ area.setPlane(makeWorkplane(partshape))
+ PathLog.debug("About to section with params: {}".format(area.getParams()))
+ sec = area.makeSections(heights=[0.0], project=True)[0].getShape()
+
+ zShift = partshape.BoundBox.ZMin - subshape.BoundBox.ZMin
+ PathLog.debug('partshapeZmin: {}, subshapeZMin: {}, zShift: {}'.format(partshape.BoundBox.ZMin, subshape.BoundBox.ZMin, zShift))
+ newPlace = FreeCAD.Placement(FreeCAD.Vector(0, 0, zShift), sec.Placement.Rotation)
+ sec.Placement = newPlace
+
+ else:
+ area = Path.Area(Fill=2, Coplanar=0).add(partshape)
+ area.setPlane(makeWorkplane(partshape))
+ sec = area.makeSections(heights=[0.0], project=True)[0].getShape()
if stockheight is not None:
eLength = float(stockheight)-partshape.BoundBox.ZMin
+ PathLog.debug('boundbox zMIN: {} elength: {}'.format(partshape.BoundBox.ZMin, eLength))
envelopeshape = sec.extrude(FreeCAD.Vector(0, 0, eLength))
else:
envelopeshape = sec.extrude(FreeCAD.Vector(0, 0, partshape.BoundBox.ZLength))
if PathLog.getLevel(PathLog.thisModule()) == PathLog.Level.DEBUG:
- removalshape=FreeCAD.ActiveDocument.addObject("Part::Feature","RemovedMaterial")
+ removalshape=FreeCAD.ActiveDocument.addObject("Part::Feature","Envelope")
removalshape.Shape = envelopeshape
return envelopeshape
-
def reverseEdge(e):
if geomType(e) == "Circle":
arcstpt = e.valueAt(e.FirstParameter)