defaults if objects pre-selected. Fixes
Smarter default for inside outside profiles first commit
This commit is contained in:
parent
bb5165634b
commit
be03c2ad26
135
src/Mod/Path/Gui/Resources/panels/ToolControl.ui
Normal file
135
src/Mod/Path/Gui/Resources/panels/ToolControl.ui
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ToolControlObject</class>
|
||||||
|
<widget class="QDialog" name="ToolControlObject">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>320</width>
|
||||||
|
<height>503</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Tool Control</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLineEdit" name="tcoName"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QFrame" name="frame_2">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="txtToolType">
|
||||||
|
<property name="text">
|
||||||
|
<string>Unknown</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="txtToolName">
|
||||||
|
<property name="text">
|
||||||
|
<string>Unknown</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="txtToolMaterial">
|
||||||
|
<property name="text">
|
||||||
|
<string>Unknown</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QComboBox" name="cboToolSelect"/>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="txtToolDiameter">
|
||||||
|
<property name="text">
|
||||||
|
<string>Unknown</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QFrame" name="frame">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Horiz. Feed</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="horizFeed"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Vert. Feed</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="vertFeed"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QFrame" name="frame_3">
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::StyledPanel</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Raised</enum>
|
||||||
|
</property>
|
||||||
|
<layout class="QFormLayout" name="formLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_3">
|
||||||
|
<property name="text">
|
||||||
|
<string>Spindle Speed (RPM)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QSpinBox" name="spindleSpeed"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="cboSpindleDirection">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Forward</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Reverse</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -120,7 +120,12 @@ class _ViewProviderLoadTool:
|
||||||
|
|
||||||
def setEdit(self, vobj, mode):
|
def setEdit(self, vobj, mode):
|
||||||
# this is executed when the object is double-clicked in the tree
|
# this is executed when the object is double-clicked in the tree
|
||||||
pass
|
FreeCADGui.Control.closeDialog()
|
||||||
|
taskd = TaskPanel()
|
||||||
|
taskd.obj = vobj.Object
|
||||||
|
FreeCADGui.Control.showDialog(taskd)
|
||||||
|
taskd.setupUi()
|
||||||
|
return True
|
||||||
|
|
||||||
def unsetEdit(self, vobj, mode):
|
def unsetEdit(self, vobj, mode):
|
||||||
# this is executed when the user cancels or terminates edit mode
|
# this is executed when the user cancels or terminates edit mode
|
||||||
|
@ -167,6 +172,119 @@ PathUtils.addToProject(obj)
|
||||||
PathUtils.addToProject(obj)
|
PathUtils.addToProject(obj)
|
||||||
|
|
||||||
|
|
||||||
|
class TaskPanel:
|
||||||
|
def __init__(self):
|
||||||
|
#self.form = FreeCADGui.PySideUic.loadUi(":/panels/ToolControl.ui")
|
||||||
|
self.form = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Path/ToolControl.ui")
|
||||||
|
self.updating = False
|
||||||
|
|
||||||
|
def accept(self):
|
||||||
|
self.getFields()
|
||||||
|
|
||||||
|
FreeCADGui.ActiveDocument.resetEdit()
|
||||||
|
FreeCADGui.Control.closeDialog()
|
||||||
|
FreeCAD.ActiveDocument.recompute()
|
||||||
|
FreeCADGui.Selection.removeObserver(self.s)
|
||||||
|
|
||||||
|
def reject(self):
|
||||||
|
FreeCADGui.Control.closeDialog()
|
||||||
|
FreeCAD.ActiveDocument.recompute()
|
||||||
|
FreeCADGui.Selection.removeObserver(self.s)
|
||||||
|
|
||||||
|
def getFields(self):
|
||||||
|
if self.obj:
|
||||||
|
|
||||||
|
if hasattr(self.obj, "VertFeed"):
|
||||||
|
self.obj.Label = self.form.tcoName.text()
|
||||||
|
|
||||||
|
if hasattr(self.obj, "VertFeed"):
|
||||||
|
self.obj.VertFeed = self.form.vertFeed.value()
|
||||||
|
if hasattr(self.obj, "HorizFeed"):
|
||||||
|
self.obj.HorizFeed = self.form.horizFeed.value()
|
||||||
|
if hasattr(self.obj, "SpindleSpeed"):
|
||||||
|
self.obj.SpindleSpeed = self.form.spindleSpeed.value()
|
||||||
|
if hasattr(self.obj, "SpindleDir"):
|
||||||
|
self.obj.SpindleDir = str(self.form.cboSpindleDirection.currentText())
|
||||||
|
if hasattr(self.obj, "ToolNumber"):
|
||||||
|
self.obj.ToolNumber = self.form.ToolNumber.value()
|
||||||
|
self.obj.Proxy.execute(self.obj)
|
||||||
|
|
||||||
|
def setFields(self):
|
||||||
|
self.form.vertFeed.setText(str(self.obj.VertFeed.Value))
|
||||||
|
self.form.horizFeed.setText(str(self.obj.HorizFeed.Value))
|
||||||
|
self.form.spindleSpeed.setText(str(self.obj.SpindleSpeed.Value))
|
||||||
|
self.form.cboSpindleDirection.setText(str(self.obj.SpindleDir.Value))
|
||||||
|
self.form.ToolNumber.setValue(self.obj.ToolNumber)
|
||||||
|
|
||||||
|
|
||||||
|
def open(self):
|
||||||
|
self.s = SelObserver()
|
||||||
|
# install the function mode resident
|
||||||
|
FreeCADGui.Selection.addObserver(self.s)
|
||||||
|
|
||||||
|
|
||||||
|
def getStandardButtons(self):
|
||||||
|
return int(QtGui.QDialogButtonBox.Ok)
|
||||||
|
|
||||||
|
def edit(self, item, column):
|
||||||
|
if not self.updating:
|
||||||
|
self.resetObject()
|
||||||
|
|
||||||
|
def resetObject(self, remove=None):
|
||||||
|
"transfers the values from the widget to the object"
|
||||||
|
# loc = []
|
||||||
|
# h = []
|
||||||
|
# l = []
|
||||||
|
# a = []
|
||||||
|
|
||||||
|
# for i in range(self.form.tagTree.topLevelItemCount()):
|
||||||
|
# it = self.form.tagTree.findItems(
|
||||||
|
# str(i+1), QtCore.Qt.MatchExactly, 0)[0]
|
||||||
|
# if (remove is None) or (remove != i):
|
||||||
|
# if it.text(1):
|
||||||
|
# x = float(it.text(1).split()[0].rstrip(","))
|
||||||
|
# y = float(it.text(1).split()[1].rstrip(","))
|
||||||
|
# z = float(it.text(1).split()[2].rstrip(","))
|
||||||
|
# loc.append(Vector(x, y, z))
|
||||||
|
|
||||||
|
# else:
|
||||||
|
# loc.append(0.0)
|
||||||
|
# if it.text(2):
|
||||||
|
# h.append(float(it.text(2)))
|
||||||
|
# else:
|
||||||
|
# h.append(4.0)
|
||||||
|
# if it.text(3):
|
||||||
|
# l.append(float(it.text(3)))
|
||||||
|
# else:
|
||||||
|
# l.append(5.0)
|
||||||
|
# if it.text(4):
|
||||||
|
# a.append(float(it.text(4)))
|
||||||
|
# else:
|
||||||
|
# a.append(45.0)
|
||||||
|
|
||||||
|
# self.obj.locs = loc
|
||||||
|
# self.obj.heights = h
|
||||||
|
# self.obj.lengths = l
|
||||||
|
# self.obj.angles = a
|
||||||
|
|
||||||
|
# self.obj.touch()
|
||||||
|
FreeCAD.ActiveDocument.recompute()
|
||||||
|
|
||||||
|
def setupUi(self):
|
||||||
|
pass
|
||||||
|
# Connect Signals and Slots
|
||||||
|
# Base Controls
|
||||||
|
# self.form.baseList.itemSelectionChanged.connect(self.itemActivated)
|
||||||
|
self.setFields()
|
||||||
|
|
||||||
|
class SelObserver:
|
||||||
|
def __init__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
if FreeCAD.GuiUp:
|
if FreeCAD.GuiUp:
|
||||||
# register the FreeCAD command
|
# register the FreeCAD command
|
||||||
FreeCADGui.addCommand('Path_LoadTool', CommandPathLoadTool())
|
FreeCADGui.addCommand('Path_LoadTool', CommandPathLoadTool())
|
||||||
|
|
|
@ -118,6 +118,23 @@ class ObjectPocket:
|
||||||
if baselist is None:
|
if baselist is None:
|
||||||
baselist = []
|
baselist = []
|
||||||
if len(baselist) == 0: # When adding the first base object, guess at heights
|
if len(baselist) == 0: # When adding the first base object, guess at heights
|
||||||
|
# try:
|
||||||
|
# bb = ss.Shape.BoundBox # parent boundbox
|
||||||
|
# subobj = ss.Shape.getElement(sub)
|
||||||
|
# fbb = subobj.BoundBox # feature boundbox
|
||||||
|
# obj.StartDepth = bb.ZMax
|
||||||
|
# obj.ClearanceHeight = bb.ZMax + 5.0
|
||||||
|
# obj.SafeHeight = bb.ZMax + 3.0
|
||||||
|
|
||||||
|
# if fbb.ZMax < bb.ZMax:
|
||||||
|
# obj.FinalDepth = fbb.ZMax
|
||||||
|
# else:
|
||||||
|
# obj.FinalDepth = bb.ZMin
|
||||||
|
# except:
|
||||||
|
# obj.StartDepth = 5.0
|
||||||
|
# obj.ClearanceHeight = 10.0
|
||||||
|
# obj.SafeHeight = 8.0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bb = ss.Shape.BoundBox # parent boundbox
|
bb = ss.Shape.BoundBox # parent boundbox
|
||||||
subobj = ss.Shape.getElement(sub)
|
subobj = ss.Shape.getElement(sub)
|
||||||
|
@ -126,15 +143,23 @@ class ObjectPocket:
|
||||||
obj.ClearanceHeight = bb.ZMax + 5.0
|
obj.ClearanceHeight = bb.ZMax + 5.0
|
||||||
obj.SafeHeight = bb.ZMax + 3.0
|
obj.SafeHeight = bb.ZMax + 3.0
|
||||||
|
|
||||||
if fbb.ZMax < bb.ZMax:
|
if fbb.ZMax == fbb.ZMin and fbb.ZMax == bb.ZMax: # top face
|
||||||
obj.FinalDepth = fbb.ZMax
|
obj.FinalDepth = bb.ZMin
|
||||||
else:
|
elif fbb.ZMax > fbb.ZMin and fbb.ZMax == bb.ZMax: # vertical face, full cut
|
||||||
|
obj.FinalDepth = fbb.ZMin
|
||||||
|
elif fbb.ZMax > fbb.ZMin and fbb.ZMin > bb.ZMin: # internal vertical wall
|
||||||
|
obj.FinalDepth = fbb.ZMin
|
||||||
|
elif fbb.ZMax == fbb.ZMin and fbb.ZMax > bb.ZMin: # face/shelf
|
||||||
|
obj.FinalDepth = fbb.ZMin
|
||||||
|
else: #catch all
|
||||||
obj.FinalDepth = bb.ZMin
|
obj.FinalDepth = bb.ZMin
|
||||||
except:
|
except:
|
||||||
obj.StartDepth = 5.0
|
obj.StartDepth = 5.0
|
||||||
obj.ClearanceHeight = 10.0
|
obj.ClearanceHeight = 10.0
|
||||||
obj.SafeHeight = 8.0
|
obj.SafeHeight = 8.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
item = (ss, sub)
|
item = (ss, sub)
|
||||||
if item in baselist:
|
if item in baselist:
|
||||||
FreeCAD.Console.PrintWarning(translate("Path", "this object already in the list" + "\n"))
|
FreeCAD.Console.PrintWarning(translate("Path", "this object already in the list" + "\n"))
|
||||||
|
@ -219,9 +244,9 @@ class ObjectPocket:
|
||||||
offsets = []
|
offsets = []
|
||||||
nextradius = self.radius
|
nextradius = self.radius
|
||||||
result = DraftGeomUtils.pocket2d(shape, nextradius)
|
result = DraftGeomUtils.pocket2d(shape, nextradius)
|
||||||
|
print "did we get something: " + str(result)
|
||||||
while result:
|
while result:
|
||||||
# print "Adding " + str(len(result)) + " wires"
|
print "Adding " + str(len(result)) + " wires"
|
||||||
offsets.extend(result)
|
offsets.extend(result)
|
||||||
nextradius += self.radius
|
nextradius += self.radius
|
||||||
result = DraftGeomUtils.pocket2d(shape, nextradius)
|
result = DraftGeomUtils.pocket2d(shape, nextradius)
|
||||||
|
@ -495,7 +520,7 @@ class CommandPathPocket:
|
||||||
FreeCADGui.doCommand('obj.StartDepth = ' + str(ztop))
|
FreeCADGui.doCommand('obj.StartDepth = ' + str(ztop))
|
||||||
FreeCADGui.doCommand('obj.FinalDepth =' + str(zbottom))
|
FreeCADGui.doCommand('obj.FinalDepth =' + str(zbottom))
|
||||||
FreeCADGui.doCommand('obj.ZigZagAngle = 45')
|
FreeCADGui.doCommand('obj.ZigZagAngle = 45')
|
||||||
FreeCADGui.doCommand('obj.UseEntry = True')
|
FreeCADGui.doCommand('obj.UseEntry = False')
|
||||||
FreeCADGui.doCommand('obj.RampAngle = 3.0')
|
FreeCADGui.doCommand('obj.RampAngle = 3.0')
|
||||||
FreeCADGui.doCommand('obj.RampSize = 0.75')
|
FreeCADGui.doCommand('obj.RampSize = 0.75')
|
||||||
FreeCADGui.doCommand('obj.HelixSize = 0.75')
|
FreeCADGui.doCommand('obj.HelixSize = 0.75')
|
||||||
|
@ -547,6 +572,24 @@ class TaskPanel:
|
||||||
self.obj.CutMode = str(self.form.cutMode.currentText())
|
self.obj.CutMode = str(self.form.cutMode.currentText())
|
||||||
self.obj.Proxy.execute(self.obj)
|
self.obj.Proxy.execute(self.obj)
|
||||||
|
|
||||||
|
def setFields(self):
|
||||||
|
self.form.startDepth.setText(str(self.obj.StartDepth.Value))
|
||||||
|
self.form.finalDepth.setText(str(self.obj.FinalDepth.Value))
|
||||||
|
self.form.safeHeight.setText(str(self.obj.SafeHeight.Value))
|
||||||
|
self.form.clearanceHeight.setText(str(self.obj.ClearanceHeight.Value))
|
||||||
|
self.form.stepDown.setValue(self.obj.StepDown)
|
||||||
|
self.form.extraOffset.setValue(self.obj.MaterialAllowance.Value)
|
||||||
|
self.form.useStartPoint.setChecked(self.obj.UseStartPoint)
|
||||||
|
|
||||||
|
index = self.form.algorithmSelect.findText(self.obj.Algorithm, QtCore.Qt.MatchFixedString)
|
||||||
|
if index >= 0:
|
||||||
|
self.form.algorithmSelect.setCurrentIndex(index)
|
||||||
|
|
||||||
|
for i in self.obj.Base:
|
||||||
|
self.form.baseList.addItem(i[0].Name + "." + i[1])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
self.s = SelObserver()
|
self.s = SelObserver()
|
||||||
# install the function mode resident
|
# install the function mode resident
|
||||||
|
@ -556,17 +599,31 @@ class TaskPanel:
|
||||||
# check that the selection contains exactly what we want
|
# check that the selection contains exactly what we want
|
||||||
selection = FreeCADGui.Selection.getSelectionEx()
|
selection = FreeCADGui.Selection.getSelectionEx()
|
||||||
|
|
||||||
if not len(selection) >= 1:
|
# if not len(selection) >= 1:
|
||||||
FreeCAD.Console.PrintError(translate("PathProject", "Please select at least one profileable object\n"))
|
# FreeCAD.Console.PrintError(translate("PathProject", "Please select at least one profileable object\n"))
|
||||||
return
|
# return
|
||||||
for s in selection:
|
# for s in selection:
|
||||||
if s.HasSubObjects:
|
# if s.HasSubObjects:
|
||||||
for i in s.SubElementNames:
|
# for i in s.SubElementNames:
|
||||||
self.obj.Proxy.addpocketbase(self.obj, s.Object, i)
|
# self.obj.Proxy.addpocketbase(self.obj, s.Object, i)
|
||||||
else:
|
# else:
|
||||||
self.obj.Proxy.addpocketbase(self.obj, s.Object)
|
# self.obj.Proxy.addpocketbase(self.obj, s.Object)
|
||||||
|
|
||||||
self.setupUi() # defaults may have changed. Reload.
|
if len(selection) != 1:
|
||||||
|
FreeCAD.Console.PrintError(translate("PathProject", "Please select only faces from one solid\n"))
|
||||||
|
return
|
||||||
|
sel = selection[0]
|
||||||
|
if not sel.HasSubObjects:
|
||||||
|
FreeCAD.Console.PrintError(translate("PathProject", "Please select faces from one solid\n"))
|
||||||
|
return
|
||||||
|
if not selection[0].SubObjects[0].ShapeType == "Face":
|
||||||
|
FreeCAD.Console.PrintError(translate("PathProject", "Please select faces from one solid\n"))
|
||||||
|
return
|
||||||
|
for i in sel.SubElementNames:
|
||||||
|
self.obj.Proxy.addpocketbase(self.obj, sel.Object, i)
|
||||||
|
|
||||||
|
|
||||||
|
self.setFields() # defaults may have changed. Reload.
|
||||||
self.form.baseList.clear()
|
self.form.baseList.clear()
|
||||||
for i in self.obj.Base:
|
for i in self.obj.Base:
|
||||||
self.form.baseList.addItem(i[0].Name + "." + i[1])
|
self.form.baseList.addItem(i[0].Name + "." + i[1])
|
||||||
|
@ -618,20 +675,6 @@ class TaskPanel:
|
||||||
self.resetObject()
|
self.resetObject()
|
||||||
|
|
||||||
def setupUi(self):
|
def setupUi(self):
|
||||||
self.form.startDepth.setText(str(self.obj.StartDepth.Value))
|
|
||||||
self.form.finalDepth.setText(str(self.obj.FinalDepth.Value))
|
|
||||||
self.form.safeHeight.setText(str(self.obj.SafeHeight.Value))
|
|
||||||
self.form.clearanceHeight.setText(str(self.obj.ClearanceHeight.Value))
|
|
||||||
self.form.stepDown.setValue(self.obj.StepDown)
|
|
||||||
self.form.extraOffset.setValue(self.obj.MaterialAllowance.Value)
|
|
||||||
self.form.useStartPoint.setChecked(self.obj.UseStartPoint)
|
|
||||||
|
|
||||||
index = self.form.algorithmSelect.findText(self.obj.Algorithm, QtCore.Qt.MatchFixedString)
|
|
||||||
if index >= 0:
|
|
||||||
self.form.algorithmSelect.setCurrentIndex(index)
|
|
||||||
|
|
||||||
for i in self.obj.Base:
|
|
||||||
self.form.baseList.addItem(i[0].Name + "." + i[1])
|
|
||||||
|
|
||||||
# Connect Signals and Slots
|
# Connect Signals and Slots
|
||||||
# Base Controls
|
# Base Controls
|
||||||
|
@ -655,6 +698,12 @@ class TaskPanel:
|
||||||
self.form.useStartPoint.clicked.connect(self.getFields)
|
self.form.useStartPoint.clicked.connect(self.getFields)
|
||||||
self.form.extraOffset.editingFinished.connect(self.getFields)
|
self.form.extraOffset.editingFinished.connect(self.getFields)
|
||||||
|
|
||||||
|
self.setFields()
|
||||||
|
|
||||||
|
sel = FreeCADGui.Selection.getSelectionEx()
|
||||||
|
if len(sel) != 0 and sel[0].HasSubObjects:
|
||||||
|
self.addBase()
|
||||||
|
|
||||||
|
|
||||||
class SelObserver:
|
class SelObserver:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -58,6 +58,7 @@ class ObjectProfile:
|
||||||
obj.addProperty("App::PropertyLinkSubList", "Base", "Path", translate("Parent Object", "The base geometry of this toolpath"))
|
obj.addProperty("App::PropertyLinkSubList", "Base", "Path", translate("Parent Object", "The base geometry of this toolpath"))
|
||||||
obj.addProperty("App::PropertyBool", "Active", "Path", translate("Path", "Make False, to prevent operation from generating code"))
|
obj.addProperty("App::PropertyBool", "Active", "Path", translate("Path", "Make False, to prevent operation from generating code"))
|
||||||
obj.addProperty("App::PropertyString", "Comment", "Path", translate("Path", "An optional comment for this profile"))
|
obj.addProperty("App::PropertyString", "Comment", "Path", translate("Path", "An optional comment for this profile"))
|
||||||
|
obj.addProperty("App::PropertyString", "UserLabel", "Path", translate("Path", "User Assigned Label"))
|
||||||
|
|
||||||
obj.addProperty("App::PropertyEnumeration", "Algorithm", "Algorithm", translate("Path", "The library or algorithm used to generate the path"))
|
obj.addProperty("App::PropertyEnumeration", "Algorithm", "Algorithm", translate("Path", "The library or algorithm used to generate the path"))
|
||||||
obj.Algorithm = ['OCC Native', 'libarea']
|
obj.Algorithm = ['OCC Native', 'libarea']
|
||||||
|
@ -120,6 +121,10 @@ class ObjectProfile:
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# def onChanged(self, obj, prop):
|
||||||
|
# if prop == "Label":
|
||||||
|
# print "we're here"
|
||||||
|
|
||||||
def addprofilebase(self, obj, ss, sub=""):
|
def addprofilebase(self, obj, ss, sub=""):
|
||||||
baselist = obj.Base
|
baselist = obj.Base
|
||||||
if len(baselist) == 0: # When adding the first base object, guess at heights
|
if len(baselist) == 0: # When adding the first base object, guess at heights
|
||||||
|
@ -146,6 +151,11 @@ class ObjectProfile:
|
||||||
obj.ClearanceHeight = 10.0
|
obj.ClearanceHeight = 10.0
|
||||||
obj.SafeHeight = 8.0
|
obj.SafeHeight = 8.0
|
||||||
|
|
||||||
|
if bb.XLength == fbb.XLength and bb.YLength == fbb.YLength:
|
||||||
|
obj.Side = "Left"
|
||||||
|
else:
|
||||||
|
obj.Side = "Right"
|
||||||
|
|
||||||
item = (ss, sub)
|
item = (ss, sub)
|
||||||
if item in baselist:
|
if item in baselist:
|
||||||
FreeCAD.Console.PrintWarning("this object already in the list" + "\n")
|
FreeCAD.Console.PrintWarning("this object already in the list" + "\n")
|
||||||
|
@ -259,6 +269,7 @@ print "y - " + str(point.y)
|
||||||
tool = PathUtils.getTool(obj, toolLoad.ToolNumber)
|
tool = PathUtils.getTool(obj, toolLoad.ToolNumber)
|
||||||
self.radius = tool.Diameter/2
|
self.radius = tool.Diameter/2
|
||||||
obj.ToolNumber = toolLoad.ToolNumber
|
obj.ToolNumber = toolLoad.ToolNumber
|
||||||
|
#obj.Label = obj.Label + "(" + toolLoad.Label + ")"
|
||||||
|
|
||||||
if obj.Base:
|
if obj.Base:
|
||||||
hfaces = []
|
hfaces = []
|
||||||
|
@ -739,7 +750,6 @@ class TaskPanel:
|
||||||
|
|
||||||
sel = FreeCADGui.Selection.getSelectionEx()
|
sel = FreeCADGui.Selection.getSelectionEx()
|
||||||
if len(sel) != 0 and sel[0].HasSubObjects:
|
if len(sel) != 0 and sel[0].HasSubObjects:
|
||||||
# if sel[0].SubObjects[0].ShapeType == "Face":
|
|
||||||
self.addBase()
|
self.addBase()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -482,6 +482,175 @@ def frange(start, stop, step, finish):
|
||||||
x.append(curdepth)
|
x.append(curdepth)
|
||||||
|
|
||||||
return x
|
return x
|
||||||
|
def rapid(x=None, y=None, z=None):
|
||||||
|
""" Returns gcode string to perform a rapid move."""
|
||||||
|
retstr = "G00"
|
||||||
|
if (x is not None) or (y is not None) or (z is not None):
|
||||||
|
if (x is not None):
|
||||||
|
retstr += " X" + str("%.4f" % x)
|
||||||
|
if (y is not None):
|
||||||
|
retstr += " Y" + str("%.4f" % y)
|
||||||
|
if (z is not None):
|
||||||
|
retstr += " Z" + str("%.4f" % z)
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
return retstr + "\n"
|
||||||
|
|
||||||
|
def feed(x=None, y=None, z=None, horizFeed=0, vertFeed=0):
|
||||||
|
""" Return gcode string to perform a linear feed."""
|
||||||
|
global feedxy
|
||||||
|
retstr = "G01 F"
|
||||||
|
if(x is None) and (y is None):
|
||||||
|
retstr += str("%.4f" % horizFeed)
|
||||||
|
else:
|
||||||
|
retstr += str("%.4f" % vertFeed)
|
||||||
|
|
||||||
|
if (x is not None) or (y is not None) or (z is not None):
|
||||||
|
if (x is not None):
|
||||||
|
retstr += " X" + str("%.4f" % x)
|
||||||
|
if (y is not None):
|
||||||
|
retstr += " Y" + str("%.4f" % y)
|
||||||
|
if (z is not None):
|
||||||
|
retstr += " Z" + str("%.4f" % z)
|
||||||
|
else:
|
||||||
|
return ""
|
||||||
|
return retstr + "\n"
|
||||||
|
|
||||||
|
def arc(cx, cy, sx, sy, ex, ey, horizFeed=0, ez=None, ccw=False):
|
||||||
|
"""
|
||||||
|
Return gcode string to perform an arc.
|
||||||
|
|
||||||
|
Assumes XY plane or helix around Z
|
||||||
|
Don't worry about starting Z- assume that's dealt with elsewhere
|
||||||
|
If start/end radii aren't within eps, abort.
|
||||||
|
|
||||||
|
cx, cy -- arc center coordinates
|
||||||
|
sx, sy -- arc start coordinates
|
||||||
|
ex, ey -- arc end coordinates
|
||||||
|
ez -- ending Z coordinate. None unless helix.
|
||||||
|
horizFeed -- horiz feed speed
|
||||||
|
ccw -- arc direction
|
||||||
|
"""
|
||||||
|
|
||||||
|
eps = 0.01
|
||||||
|
if (math.sqrt((cx - sx)**2 + (cy - sy)**2) - math.sqrt((cx - ex)**2 + (cy - ey)**2)) >= eps:
|
||||||
|
print "ERROR: Illegal arc: Start and end radii not equal"
|
||||||
|
return ""
|
||||||
|
|
||||||
|
retstr = ""
|
||||||
|
if ccw:
|
||||||
|
retstr += "G03 F" + str(horizFeed)
|
||||||
|
else:
|
||||||
|
retstr += "G02 F" + str(horizFeed)
|
||||||
|
|
||||||
|
retstr += " X" + str("%.4f" % ex) + " Y" + str("%.4f" % ey)
|
||||||
|
|
||||||
|
if ez is not None:
|
||||||
|
retstr += " Z" + str("%.4f" % ez)
|
||||||
|
|
||||||
|
retstr += " I" + str("%.4f" % (cx - sx)) + " J" + str("%.4f" % (cy - sy))
|
||||||
|
|
||||||
|
return retstr + "\n"
|
||||||
|
|
||||||
|
def helicalPlunge(plungePos, rampangle, destZ, startZ, toold, plungeR, horizFeed):
|
||||||
|
"""
|
||||||
|
Return gcode string to perform helical entry move.
|
||||||
|
|
||||||
|
plungePos -- vector of the helical entry location
|
||||||
|
destZ -- the lowest Z position or milling level
|
||||||
|
startZ -- Starting Z position for helical move
|
||||||
|
rampangle -- entry angle
|
||||||
|
toold -- tool diameter
|
||||||
|
plungeR -- the radius of the entry helix
|
||||||
|
"""
|
||||||
|
# toold = self.radius * 2
|
||||||
|
|
||||||
|
helixCmds = "(START HELICAL PLUNGE)\n"
|
||||||
|
if(plungePos is None):
|
||||||
|
raise Exception("Helical plunging requires a position!")
|
||||||
|
return None
|
||||||
|
|
||||||
|
helixX = plungePos.x + toold/2 * plungeR
|
||||||
|
helixY = plungePos.y
|
||||||
|
|
||||||
|
helixCirc = math.pi * toold * plungeR
|
||||||
|
dzPerRev = math.sin(rampangle/180. * math.pi) * helixCirc
|
||||||
|
|
||||||
|
# Go to the start of the helix position
|
||||||
|
helixCmds += rapid(helixX, helixY)
|
||||||
|
helixCmds += rapid(z=startZ)
|
||||||
|
|
||||||
|
# Helix as required to get to the requested depth
|
||||||
|
lastZ = startZ
|
||||||
|
curZ = max(startZ-dzPerRev, destZ)
|
||||||
|
done = False
|
||||||
|
while not done:
|
||||||
|
done = (curZ == destZ)
|
||||||
|
# NOTE: FreeCAD doesn't render this, but at least LinuxCNC considers it valid
|
||||||
|
# helixCmds += arc(plungePos.x, plungePos.y, helixX, helixY, helixX, helixY, ez = curZ, ccw=True)
|
||||||
|
|
||||||
|
# Use two half-helixes; FreeCAD renders that correctly,
|
||||||
|
# and it fits with the other code breaking up 360-degree arcs
|
||||||
|
helixCmds += arc(plungePos.x, plungePos.y, helixX, helixY, helixX - toold * plungeR, helixY, horizFeed, ez=(curZ + lastZ)/2., ccw=True)
|
||||||
|
helixCmds += arc(plungePos.x, plungePos.y, helixX - toold * plungeR, helixY, helixX, helixY, horizFeed, ez=curZ, ccw=True)
|
||||||
|
lastZ = curZ
|
||||||
|
curZ = max(curZ - dzPerRev, destZ)
|
||||||
|
|
||||||
|
return helixCmds
|
||||||
|
|
||||||
|
def rampPlunge(edge, rampangle, destZ, startZ):
|
||||||
|
"""
|
||||||
|
Return gcode string to linearly ramp down to milling level.
|
||||||
|
|
||||||
|
edge -- edge to follow
|
||||||
|
rampangle -- entry angle
|
||||||
|
destZ -- Final Z depth
|
||||||
|
startZ -- Starting Z depth
|
||||||
|
|
||||||
|
FIXME: This ramps along the first edge, assuming it's long
|
||||||
|
enough, NOT just wiggling back and forth by ~0.75 * toolD.
|
||||||
|
Not sure if that's any worse, but it's simpler
|
||||||
|
I think this should be changed to be limited to a maximum ramp size. Otherwise machine time will get longer than it needs to be.
|
||||||
|
"""
|
||||||
|
|
||||||
|
rampCmds = "(START RAMP PLUNGE)\n"
|
||||||
|
if(edge is None):
|
||||||
|
raise Exception("Ramp plunging requires an edge!")
|
||||||
|
return None
|
||||||
|
|
||||||
|
sPoint = edge.Vertexes[0].Point
|
||||||
|
ePoint = edge.Vertexes[1].Point
|
||||||
|
# Evidently edges can get flipped- pick the right one in this case
|
||||||
|
# FIXME: This is iffy code, based on what already existed in the "for vpos ..." loop below
|
||||||
|
if ePoint == sPoint:
|
||||||
|
# print "FLIP"
|
||||||
|
ePoint = edge.Vertexes[-1].Point
|
||||||
|
|
||||||
|
rampDist = edge.Length
|
||||||
|
rampDZ = math.sin(rampangle/180. * math.pi) * rampDist
|
||||||
|
|
||||||
|
rampCmds += rapid(sPoint.x, sPoint.y)
|
||||||
|
rampCmds += rapid(z=startZ)
|
||||||
|
|
||||||
|
# Ramp down to the requested depth
|
||||||
|
# FIXME: This might be an arc, so handle that as well
|
||||||
|
|
||||||
|
curZ = max(startZ-rampDZ, destZ)
|
||||||
|
done = False
|
||||||
|
while not done:
|
||||||
|
done = (curZ == destZ)
|
||||||
|
|
||||||
|
# If it's an arc, handle it!
|
||||||
|
if isinstance(edge.Curve, Part.Circle):
|
||||||
|
raise Exception("rampPlunge: Screw it, not handling an arc.")
|
||||||
|
# Straight feed! Easy!
|
||||||
|
else:
|
||||||
|
rampCmds += feed(ePoint.x, ePoint.y, curZ)
|
||||||
|
rampCmds += feed(sPoint.x, sPoint.y)
|
||||||
|
|
||||||
|
curZ = max(curZ - rampDZ, destZ)
|
||||||
|
|
||||||
|
return rampCmds
|
||||||
|
|
||||||
|
|
||||||
class depth_params:
|
class depth_params:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user