[CAM] separate controls for feed rate percent entrance vs exit

This commit is contained in:
David Kaufman
2025-08-22 14:25:56 -04:00
parent 9c5e8f8340
commit 093152b1dc
2 changed files with 101 additions and 36 deletions

View File

@@ -177,14 +177,14 @@
<item row="0" column="0">
<widget class="QLabel" name="label_feed_rate_percent">
<property name="text">
<string>Feed Rate Percent</string>
<string>Entrance Feed Rate Percent</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="dspFeedRatePercent">
<widget class="QDoubleSpinBox" name="dspFeedRatePercentIn">
<property name="toolTip">
<string>Horizontal feed rate during entrances and exits, as a percentage of the normal feed rate.</string>
<string>Feed rate to use when entering a cut, as a percentage of the normal feed rate.</string>
</property>
<property name="decimals">
<number>0</number>
@@ -196,7 +196,7 @@
<double>999999.000000000000000</double>
</property>
<property name="singleStep">
<double>10.000000000000000</double>
<double>5.000000000000000</double>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
@@ -204,6 +204,35 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_feed_rate_percent">
<property name="text">
<string>Exit Feed Rate Percent</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDoubleSpinBox" name="dspFeedRatePercentOut">
<property name="toolTip">
<string>Feed rate to use when exiting a cut, as a percentage of the normal feed rate.</string>
</property>
<property name="decimals">
<number>0</number>
</property>
<property name="minimum">
<double>1.000000000000000</double>
</property>
<property name="maximum">
<double>999999.000000000000000</double>
</property>
<property name="singleStep">
<double>5.000000000000000</double>
</property>
<property name="unit" stdset="0">
<string notr="true"/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="chkRapidPlunge">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">

View File

@@ -164,11 +164,20 @@ class ObjectDressup:
)
obj.addProperty(
"App::PropertyInteger",
"FeedRatePercent",
"FeedRatePercentIn",
"Path",
QT_TRANSLATE_NOOP(
"App::Property",
"Percentage modifier to apply to feed rate while entering and exiting",
"Percentage modifier to apply to feed rate while entering the cut",
),
)
obj.addProperty(
"App::PropertyInteger",
"FeedRatePercentOut",
"Path",
QT_TRANSLATE_NOOP(
"App::Property",
"Percentage modifier to apply to feed rate while exiting the cut",
),
)
obj.Proxy = self
@@ -188,7 +197,8 @@ class ObjectDressup:
obj.LeadOut = True
obj.AngleIn = 90
obj.AngleOut = 90
obj.FeedRatePercent = 100
obj.FeedRatePercentIn = 100
obj.FeedRatePercentOut = 100
obj.InvertIn = False
obj.InvertOut = False
obj.RapidPlunge = False
@@ -261,8 +271,10 @@ class ObjectDressup:
)
return
self.horizFeed = self.toolController.HorizFeed.Value * obj.FeedRatePercent / 100
self.horizFeed = self.toolController.HorizFeed.Value
self.vertFeed = self.toolController.VertFeed.Value
self.entranceFeed = self.horizFeed * obj.FeedRatePercentIn / 100
self.exitFeed = self.horizFeed * obj.FeedRatePercentOut / 100
obj.Path = self.generateLeadInOutCurve(obj)
@@ -429,17 +441,28 @@ class ObjectDressup:
obj.setEditorMode(k + "In", 2 if obj.StyleIn in v else 0)
obj.setEditorMode(k + "Out", 2 if obj.StyleOut in v else 0)
if not hasattr(obj, "FeedRatePercent"):
if not hasattr(obj, "FeedRatePercentIn"):
obj.addProperty(
"App::PropertyInteger",
"FeedRatePercent",
"FeedRatePercentIn",
"Path",
QT_TRANSLATE_NOOP(
"App::Property",
"Percentage modifier to apply to feed rate while entering and exiting",
"Percentage modifier to apply to feed rate while entering the cut",
),
)
obj.FeedRatePercent = 100
obj.FeedRatePercentIn = 100
if not hasattr(obj, "FeedRatePercentOut"):
obj.addProperty(
"App::PropertyInteger",
"FeedRatePercentOut",
"Path",
QT_TRANSLATE_NOOP(
"App::Property",
"Percentage modifier to apply to feed rate while exiting the cut",
),
)
obj.FeedRatePercentOut = 100
# Get direction for lead-in/lead-out in XY plane
def getLeadDir(self, obj, invert=False):
@@ -521,14 +544,14 @@ class ObjectDressup:
return App.Vector(math.cos(angle), math.sin(angle), 0)
# Create arc in XY plane with automatic detection G2|G3
def createArcMove(self, obj, begin, end, offset, invert=False):
def createArcMove(self, obj, begin, end, offset, invert, feedRate):
param = {
"X": end.x,
"Y": end.y,
"Z": end.z,
"I": offset.x,
"J": offset.y,
"F": self.horizFeed,
"F": feedRate,
}
if self.getLeadDir(obj, invert) > 0:
command = PathLanguage.MoveArcCCW(begin, "G3", param)
@@ -538,8 +561,8 @@ class ObjectDressup:
return command
# Create arc in XY plane with manually set G2|G3
def createArcMoveN(self, obj, begin, end, offset, cmdName):
param = {"X": end.x, "Y": end.y, "I": offset.x, "J": offset.y, "F": self.horizFeed}
def createArcMoveN(self, obj, begin, end, offset, cmdName, feedRate):
param = {"X": end.x, "Y": end.y, "I": offset.x, "J": offset.y, "F": feedRate}
if cmdName == "G2":
command = PathLanguage.MoveArcCW(begin, cmdName, param)
else:
@@ -548,8 +571,8 @@ class ObjectDressup:
return command
# Create line movement G1
def createStraightMove(self, obj, begin, end):
param = {"X": end.x, "Y": end.y, "Z": end.z, "F": self.horizFeed}
def createStraightMove(self, obj, begin, end, feedRate):
param = {"X": end.x, "Y": end.y, "Z": end.z, "F": feedRate}
command = PathLanguage.MoveStraight(begin, "G1", param)
return command
@@ -571,7 +594,7 @@ class ObjectDressup:
return stepAngle
# Create vertical arc with move Down by line segments
def createArcZMoveDown(self, obj, begin, end, radius):
def createArcZMoveDown(self, obj, begin, end, radius, feedRate):
commands = []
angle = math.acos((radius - begin.z + end.z) / radius) # start angle
stepAngle = self.getStepAngleArcZ(obj, radius)
@@ -590,7 +613,7 @@ class ObjectDressup:
else:
# exclude error of calculations for the last iteration
iterEnd = copy.copy(end)
param = {"X": iterEnd.x, "Y": iterEnd.y, "Z": iterEnd.z, "F": self.horizFeed}
param = {"X": iterEnd.x, "Y": iterEnd.y, "Z": iterEnd.z, "F": feedRate}
commands.append(PathLanguage.MoveStraight(iterBegin, "G1", param))
iterBegin = copy.copy(iterEnd)
iter += 1
@@ -598,7 +621,7 @@ class ObjectDressup:
return commands
# Create vertical arc with move Up by line segments
def createArcZMoveUp(self, obj, begin, end, radius):
def createArcZMoveUp(self, obj, begin, end, radius, feedRate):
commands = []
angleMax = math.acos((radius - end.z + begin.z) / radius) # finish angle
stepAngle = self.getStepAngleArcZ(obj, radius)
@@ -618,7 +641,7 @@ class ObjectDressup:
else:
# exclude the error of calculations of the last point
iterEnd = copy.copy(end)
param = {"X": iterEnd.x, "Y": iterEnd.y, "Z": iterEnd.z, "F": self.horizFeed}
param = {"X": iterEnd.x, "Y": iterEnd.y, "Z": iterEnd.z, "F": feedRate}
commands.append(PathLanguage.MoveStraight(iterBegin, "G1", param))
iterBegin = copy.copy(iterEnd)
iter += 1
@@ -676,7 +699,11 @@ class ObjectDressup:
arcBegin = begin + tangent + normal
arcCenter = begin + normalMax
arcOffset = arcCenter - arcBegin
lead.append(self.createArcMove(obj, arcBegin, begin, arcOffset, obj.InvertIn))
lead.append(
self.createArcMove(
obj, arcBegin, begin, arcOffset, obj.InvertIn, self.entranceFeed
)
)
# prepend "Line" style lead-in - line in XY
# Line3d the same as Line, but increased Z start point
@@ -690,7 +717,7 @@ class ObjectDressup:
* normalLength
)
lineBegin = begin + tangent + normal
lead.append(self.createStraightMove(obj, lineBegin, begin))
lead.append(self.createStraightMove(obj, lineBegin, begin, self.entranceFeed))
# prepend "LineZ" style lead-in - vertical inclined line
# Should be apply only on straight Path segment
@@ -705,7 +732,7 @@ class ObjectDressup:
tangent = -self.angleToVector(angleTangent) * tangentLength
normal = App.Vector(0, 0, normalLength)
lineBegin = begin + tangent + normal
lead.append(self.createStraightMove(obj, lineBegin, begin))
lead.append(self.createStraightMove(obj, lineBegin, begin, self.entranceFeed))
# prepend "ArcZ" style lead-in - vertical Arc
# Should be apply only on straight Path segment
@@ -724,7 +751,9 @@ class ObjectDressup:
tangent = -self.angleToVector(angleTangent) * tangentLength
normal = App.Vector(0, 0, normalLength)
arcBegin = begin + tangent + normal
lead.extend(self.createArcZMoveDown(obj, arcBegin, begin, arcRadius))
lead.extend(
self.createArcZMoveDown(obj, arcBegin, begin, arcRadius, self.entranceFeed)
)
# replace 'begin' position by first lead-in command
begin = lead[0].positionBegin()
@@ -764,7 +793,7 @@ class ObjectDressup:
travelToStart = self.getTravelStart(obj, begin, first, outInstrPrev)
else:
# exclude any lead-in commands
param = {"X": begin.x, "Y": begin.y, "Z": begin.z, "F": self.horizFeed}
param = {"X": begin.x, "Y": begin.y, "Z": begin.z, "F": self.entranceFeed}
travelToStart = [PathLanguage.MoveStraight(None, "G01", param)]
lead = travelToStart + lead
@@ -812,7 +841,11 @@ class ObjectDressup:
* normalLength
)
arcEnd = end + tangent + normal
lead.append(self.createArcMove(obj, end, arcEnd, normalMax, obj.InvertOut))
lead.append(
self.createArcMove(
obj, end, arcEnd, normalMax, obj.InvertOut, self.exitFeed
)
)
# append "Line" style lead-out
# Line3d the same as Line, but increased Z start point
@@ -826,7 +859,7 @@ class ObjectDressup:
* normalLength
)
lineEnd = end + tangent + normal
lead.append(self.createStraightMove(obj, end, lineEnd))
lead.append(self.createStraightMove(obj, end, lineEnd, self.exitFeed))
# append "LineZ" style lead-out - vertical inclined line
# Should be apply only on straight Path segment
@@ -841,7 +874,7 @@ class ObjectDressup:
tangent = self.angleToVector(angleTangent) * tangentLength
normal = App.Vector(0, 0, normalLength)
lineEnd = end + tangent + normal
lead.append(self.createStraightMove(obj, end, lineEnd))
lead.append(self.createStraightMove(obj, end, lineEnd, self.exitFeed))
# prepend "ArcZ" style lead-out - vertical Arc
# Should be apply only on straight Path segment
@@ -860,7 +893,9 @@ class ObjectDressup:
tangent = self.angleToVector(angleTangent) * tangentLength
normal = App.Vector(0, 0, normalLength)
arcEnd = end + tangent + normal
lead.extend(self.createArcZMoveUp(obj, end, arcEnd, arcRadius))
lead.extend(
self.createArcZMoveUp(obj, end, arcEnd, arcRadius, self.exitFeed)
)
if obj.StyleOut in ("Arc3d", "Line3d"):
# Up Z end point for Arc3d and Line3d
@@ -1018,7 +1053,7 @@ class ObjectDressup:
n = math.hypot(v.x, v.y)
u = v / n
cutEnd = begin + u * newLength
command = self.createStraightMove(obj, begin, cutEnd)
command = self.createStraightMove(obj, begin, cutEnd, self.horizFeed)
# Cut arc move from begin
elif instr.isArc():
@@ -1033,7 +1068,7 @@ class ObjectDressup:
normal = self.angleToVector(angleTangent + self.getPathDir(obj)) * normalLength
arcEnd = arcBegin + tangent + normal
cmdName = "G2" if instr.isCW() else "G3"
command = self.createArcMoveN(obj, arcBegin, arcEnd, arcOffset, cmdName)
command = self.createArcMoveN(obj, arcBegin, arcEnd, arcOffset, cmdName, self.horizFeed)
return command
@@ -1047,7 +1082,7 @@ class ObjectDressup:
n = math.hypot(v.x, v.y)
u = v / n
newBegin = end - u * newLength
command = self.createStraightMove(obj, newBegin, end)
command = self.createStraightMove(obj, newBegin, end, self.horizFeed)
return command
# Cut arc move from begin
@@ -1064,7 +1099,7 @@ class ObjectDressup:
arcBegin = arcEnd + tangent + normal
arcOffset = arcCenter - arcBegin
cmdName = "G2" if instr.isCW() else "G3"
command = self.createArcMoveN(obj, arcBegin, arcEnd, arcOffset, cmdName)
command = self.createArcMoveN(obj, arcBegin, arcEnd, arcOffset, cmdName, self.horizFeed)
return command
return None
@@ -1210,7 +1245,8 @@ class TaskDressupLeadInOut(SimpleEditPanel):
def setupSpinBoxes(self):
self.connectWidget("InvertIn", self.form.chkInvertDirectionIn)
self.connectWidget("InvertOut", self.form.chkInvertDirectionOut)
self.connectWidget("FeedRatePercent", self.form.dspFeedRatePercent)
self.connectWidget("FeedRatePercentIn", self.form.dspFeedRatePercentIn)
self.connectWidget("FeedRatePercentOut", self.form.dspFeedRatePercentOut)
self.connectWidget("PercentageRadiusIn", self.form.dspPercentageRadiusIn)
self.connectWidget("PercentageRadiusOut", self.form.dspPercentageRadiusOut)
self.connectWidget("StyleIn", self.form.cboStyleIn)