Path: usecomp setting toggles the availability of the side property
This commit is contained in:
committed by
Yorik van Havre
parent
0766a7387f
commit
cc4abd21b9
@@ -33,8 +33,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>381</height>
|
||||
<width>285</width>
|
||||
<height>277</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="icon">
|
||||
@@ -111,8 +111,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>381</height>
|
||||
<width>120</width>
|
||||
<height>96</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="icon">
|
||||
@@ -178,8 +178,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>381</width>
|
||||
<height>381</height>
|
||||
<width>154</width>
|
||||
<height>68</height>
|
||||
</rect>
|
||||
</property>
|
||||
<attribute name="icon">
|
||||
@@ -343,13 +343,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Roll Radius</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="Gui::InputField" name="extraOffset">
|
||||
<property name="minimum">
|
||||
@@ -360,16 +353,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="Gui::InputField" name="rollRadius">
|
||||
<property name="minimum">
|
||||
<double>0.000000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -390,13 +373,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="useEndPoint">
|
||||
<property name="text">
|
||||
<string>Use End Point</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="useStartPoint">
|
||||
<property name="text">
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user