diff --git a/src/Mod/CAM/CAMTests/TestPathAdaptive.py b/src/Mod/CAM/CAMTests/TestPathAdaptive.py index ab3b498e34..bbef17870a 100644 --- a/src/Mod/CAM/CAMTests/TestPathAdaptive.py +++ b/src/Mod/CAM/CAMTests/TestPathAdaptive.py @@ -115,7 +115,6 @@ class TestPathAdaptive(PathTestBase): # setDepthsAndHeights(adaptive) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = False @@ -149,7 +148,6 @@ class TestPathAdaptive(PathTestBase): # setDepthsAndHeights(adaptive) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = False @@ -177,7 +175,6 @@ class TestPathAdaptive(PathTestBase): # setDepthsAndHeights(adaptive) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = True @@ -218,7 +215,6 @@ class TestPathAdaptive(PathTestBase): # setDepthsAndHeights(adaptive) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = False @@ -261,7 +257,6 @@ class TestPathAdaptive(PathTestBase): # setDepthsAndHeights(adaptive) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = False @@ -304,7 +299,6 @@ class TestPathAdaptive(PathTestBase): # setDepthsAndHeights(adaptive) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = False @@ -347,7 +341,6 @@ class TestPathAdaptive(PathTestBase): # setDepthsAndHeights(adaptive) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = False @@ -408,7 +401,6 @@ class TestPathAdaptive(PathTestBase): setDepthsAndHeights(adaptive, 15, 0) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = False @@ -478,7 +470,6 @@ class TestPathAdaptive(PathTestBase): setDepthsAndHeights(adaptive, 15, 10) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = False @@ -540,7 +531,6 @@ class TestPathAdaptive(PathTestBase): setDepthsAndHeights(adaptive, 15, 0) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = False @@ -622,7 +612,6 @@ class TestPathAdaptive(PathTestBase): setDepthsAndHeights(adaptive, 15, 5) adaptive.FinishingProfile = False adaptive.HelixAngle = 75.0 - adaptive.HelixDiameterLimit.Value = 1.0 adaptive.LiftDistance.Value = 1.0 adaptive.StepOver = 75 adaptive.UseOutline = False diff --git a/src/Mod/CAM/Gui/Resources/panels/PageOpAdaptiveEdit.ui b/src/Mod/CAM/Gui/Resources/panels/PageOpAdaptiveEdit.ui index d2b1d43549..fa6b76ab74 100644 --- a/src/Mod/CAM/Gui/Resources/panels/PageOpAdaptiveEdit.ui +++ b/src/Mod/CAM/Gui/Resources/panels/PageOpAdaptiveEdit.ui @@ -66,7 +66,7 @@ - + Accuracy vs performance @@ -164,29 +164,15 @@ Larger values (further to the right) will calculate faster; smaller values (furt 100 + + % + - Step over percent - - - - - - - Angle of the helix entry cone - - - - - - - - - - Helix ramp angle + Step over @@ -221,33 +207,6 @@ Larger values (further to the right) will calculate faster; smaller values (furt - - - - If greater than zero it limits the helix ramp diameter, otherwise 75 percent of tool diameter is used - - - - - - - - - - Helix cone angle - - - - - - - Angle of the helix ramp entry - - - - - - @@ -272,10 +231,131 @@ Larger values (further to the right) will calculate faster; smaller values (furt + + + + + + + QFrame::Shape::StyledPanel + + + QFrame::Shadow::Raised + + + + + + <b>Helix Parameters</b> + + + + + + + Max stepdown + + + + + + + The maximum allowable descent in a single revolution of the helix. + + + + + + + + + + Ramp angle + + + + + + + Angle of the helix ramp entry + + + + + + + + + + Cone angle + + + + + + + Angle of the helix entry cone + + + + + + - Helix max diameter + Max diameter + + + + + + + Maximum (and nominal) helix entry diameter, as a percentage of the tool diameter. + + + 10 + + + 100 + + + 5 + + + % + + + 1 + + + + + + + Min diameter + + + + + + + Minimum acceptable entry diameter, as a percentage of the tool diameter. + + + 10 + + + 100 + + + 5 + + + % + + + 1 diff --git a/src/Mod/CAM/Path/Op/Adaptive.py b/src/Mod/CAM/Path/Op/Adaptive.py index 4d8fb39dce..b6a69f7fd8 100644 --- a/src/Mod/CAM/Path/Op/Adaptive.py +++ b/src/Mod/CAM/Path/Op/Adaptive.py @@ -118,7 +118,7 @@ def discretize(edge, flipDirection=False): return pts -def GenerateGCode(op, obj, adaptiveResults, helixDiameter): +def GenerateGCode(op, obj, adaptiveResults): if not adaptiveResults or not adaptiveResults[0]["AdaptivePaths"]: return @@ -138,6 +138,8 @@ def GenerateGCode(op, obj, adaptiveResults, helixDiameter): helixAngleRad = math.radians(obj.HelixAngle) depthPerOneCircle = length * math.tan(helixAngleRad) + if obj.HelixMaxStepdown.Value != 0 and obj.HelixMaxStepdown.Value < depthPerOneCircle: + depthPerOneCircle = obj.HelixMaxStepdown.Value stepUp = max(obj.LiftDistance.Value, 0) @@ -538,7 +540,11 @@ def Execute(op, obj): FreeCADGui.updateGui() try: - helixDiameter = obj.HelixDiameterLimit.Value + obj.HelixMinDiameterPercent = max(obj.HelixMinDiameterPercent, 10) + obj.HelixMaxDiameterPercent = max(obj.HelixMaxDiameterPercent, obj.HelixMinDiameterPercent) + + helixDiameter = obj.HelixMaxDiameterPercent / 100 * op.tool.Diameter.Value + helixMinDiameter = obj.HelixMinDiameterPercent / 100 * op.tool.Diameter.Value topZ = op.stock.Shape.BoundBox.ZMax obj.Stopped = False obj.StopProcessing = False @@ -592,6 +598,7 @@ def Execute(op, obj): "stockGeometry": stockPath2d, "stepover": float(obj.StepOver), "effectiveHelixDiameter": float(helixDiameter), + "helixMinDiameter": float(helixMinDiameter), "operationType": obj.OperationType, "side": obj.Side, "forceInsideOut": obj.ForceInsideOut, @@ -633,7 +640,8 @@ def Execute(op, obj): a2d = area.Adaptive2d() a2d.stepOverFactor = 0.01 * obj.StepOver a2d.toolDiameter = float(op.tool.Diameter) - a2d.helixRampDiameter = helixDiameter + a2d.helixRampTargetDiameter = helixDiameter + a2d.helixRampMinDiameter = helixMinDiameter a2d.keepToolDownDistRatio = keepToolDownRatio a2d.stockToLeave = float(obj.StockToLeave) a2d.tolerance = float(obj.Tolerance) @@ -657,7 +665,7 @@ def Execute(op, obj): ) # GENERATE - GenerateGCode(op, obj, adaptiveResults, helixDiameter) + GenerateGCode(op, obj, adaptiveResults) if not obj.StopProcessing: Path.Log.info("*** Done. Elapsed time: %f sec\n\n" % (time.time() - start)) @@ -699,7 +707,12 @@ def ExecuteModelAware(op, obj): FreeCADGui.updateGui() try: - helixDiameter = obj.HelixDiameterLimit.Value + obj.HelixMinDiameterPercent = max(obj.HelixMinDiameterPercent, 10) + obj.HelixMaxDiameterPercent = max(obj.HelixMaxDiameterPercent, obj.HelixMinDiameterPercent) + obj.StepOver = max(obj.StepOver, 1) + + helixDiameter = obj.HelixMaxDiameterPercent / 100 * op.tool.Diameter.Value + helixMinDiameter = obj.HelixMinDiameterPercent / 100 * op.tool.Diameter.Value topZ = op.stock.Shape.BoundBox.ZMax obj.Stopped = False obj.StopProcessing = False @@ -774,6 +787,7 @@ def ExecuteModelAware(op, obj): "stockGeometry": stockPaths, "stepover": obj.StepOver, "effectiveHelixDiameter": helixDiameter, + "helixMinDiameter": helixMinDiameter, "operationType": "Clearing", "side": "Outside", "forceInsideOut": obj.ForceInsideOut, @@ -793,6 +807,7 @@ def ExecuteModelAware(op, obj): "stockGeometry": stockPaths, "stepover": obj.StepOver, "effectiveHelixDiameter": helixDiameter, + "helixMinDiameter": helixMinDiameter, "operationType": "Clearing", "side": "Inside", "forceInsideOut": obj.ForceInsideOut, @@ -857,7 +872,8 @@ def ExecuteModelAware(op, obj): a2d = area.Adaptive2d() a2d.stepOverFactor = 0.01 * obj.StepOver a2d.toolDiameter = op.tool.Diameter.Value - a2d.helixRampDiameter = helixDiameter + a2d.helixRampTargetDiameter = helixDiameter + a2d.helixRampMinDiameter = helixMinDiameter a2d.keepToolDownDistRatio = keepToolDownRatio # NOTE: Z stock is handled in our stepdowns a2d.stockToLeave = obj.StockToLeave.Value @@ -946,7 +962,7 @@ def ExecuteModelAware(op, obj): ) # GENERATE - GenerateGCode(op, obj, adaptiveResults, helixDiameter) + GenerateGCode(op, obj, adaptiveResults) if not obj.StopProcessing: Path.Log.info("*** Done. Elapsed time: %f sec\n\n" % (time.time() - start)) @@ -1800,6 +1816,15 @@ class PathAdaptive(PathOp.ObjectOp): "Helix ramp entry angle (degrees)", ), ) + obj.addProperty( + "App::PropertyLength", + "HelixMaxStepdown", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "The maximum allowable descent in a single revolution of the helix.", + ), + ) obj.addProperty( "App::PropertyAngle", "HelixConeAngle", @@ -1810,12 +1835,21 @@ class PathAdaptive(PathOp.ObjectOp): ), ) obj.addProperty( - "App::PropertyLength", - "HelixDiameterLimit", + "App::PropertyPercent", + "HelixMaxDiameterPercent", "Adaptive", QT_TRANSLATE_NOOP( "App::Property", - "Limit helix entry diameter, if limit larger than tool diameter or 0, tool diameter is used", + "Maximum (and nominal) helix entry diameter, as a percentage of the tool diameter", + ), + ) + obj.addProperty( + "App::PropertyPercent", + "HelixMinDiameterPercent", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Minimum acceptable helix entry diameter, as a percentage of the tool diameter", ), ) obj.addProperty( @@ -1874,7 +1908,8 @@ class PathAdaptive(PathOp.ObjectOp): obj.StopProcessing = False obj.HelixAngle = 5 obj.HelixConeAngle = 0 - obj.HelixDiameterLimit = 0.0 + obj.HelixMaxDiameterPercent = 100 + obj.HelixMinDiameterPercent = 10 obj.AdaptiveInputState = "" obj.AdaptiveOutputState = "" obj.StockToLeave = 0 @@ -1964,6 +1999,44 @@ class PathAdaptive(PathOp.ObjectOp): obj.addProperty("Part::PropertyPartShape", "removalshape", "Path", "") obj.setEditorMode("removalshape", 2) # hide + if hasattr(obj, "HelixDiameterLimit"): + oldD = obj.HelixDiameterLimit.Value + obj.removeProperty("HelixDiameterLimit") + obj.addProperty( + "App::PropertyPercent", + "HelixMaxDiameterPercent", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Maximum (and nominal) helix entry diameter, as a percentage of the tool diameter", + ), + ) + obj.addProperty( + "App::PropertyPercent", + "HelixMinDiameterPercent", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "Minimum acceptable helix entry diameter, as a percentage of the tool diameter", + ), + ) + obj.HelixMinDiameterPercent = 10 + if hasattr(obj, "ToolController"): + obj.HelixMaxDiameterPercent = int( + 75 if oldD == 0 else 100 * oldD / obj.ToolController.Tool.Diameter.Value + ) + + if not hasattr(obj, "HelixMaxStepdown"): + obj.addProperty( + "App::PropertyLength", + "HelixMaxStepdown", + "Adaptive", + QT_TRANSLATE_NOOP( + "App::Property", + "The maximum allowable descent in a single revolution of the helix.", + ), + ) + FeatureExtensions.initialize_properties(obj) @@ -1986,7 +2059,8 @@ def SetupProperties(): "AdaptiveOutputState", "HelixAngle", "HelixConeAngle", - "HelixDiameterLimit", + "HelixMaxDiameterPercent", + "HelixMinDiameterPercent", "UseOutline", "OrderCutsByRegion", ] diff --git a/src/Mod/CAM/Path/Op/Gui/Adaptive.py b/src/Mod/CAM/Path/Op/Gui/Adaptive.py index 3e94602ca0..70c98b3ef4 100644 --- a/src/Mod/CAM/Path/Op/Gui/Adaptive.py +++ b/src/Mod/CAM/Path/Op/Gui/Adaptive.py @@ -45,10 +45,9 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): return form def initPage(self, obj): + self.form.HelixMaxStepdown.setProperty("unit", obj.HelixMaxStepdown.getUserPreferred()[2]) + self.form.LiftDistance.setProperty("unit", obj.LiftDistance.getUserPreferred()[2]) - self.form.HelixDiameterLimit.setProperty( - "unit", obj.HelixDiameterLimit.getUserPreferred()[2] - ) self.form.KeepToolDownRatio.setProperty("unit", obj.KeepToolDownRatio.getUserPreferred()[2]) self.form.StockToLeave.setProperty("unit", obj.StockToLeave.getUserPreferred()[2]) @@ -61,8 +60,10 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): signals.append(self.form.stepOverPercent.valueChanged) signals.append(self.form.Tolerance.valueChanged) signals.append(self.form.HelixAngle.valueChanged) + signals.append(self.form.HelixMaxStepdown.valueChanged) signals.append(self.form.HelixConeAngle.valueChanged) - signals.append(self.form.HelixDiameterLimit.valueChanged) + signals.append(self.form.HelixMaxDiameterPercent.valueChanged) + signals.append(self.form.HelixMinDiameterPercent.valueChanged) signals.append(self.form.LiftDistance.valueChanged) signals.append(self.form.KeepToolDownRatio.valueChanged) signals.append(self.form.StockToLeave.valueChanged) @@ -88,11 +89,14 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): FreeCAD.Units.Quantity(obj.HelixAngle, FreeCAD.Units.Angle).UserString ) + self.form.HelixMaxStepdown.setProperty("rawValue", obj.HelixMaxStepdown.Value) + self.form.HelixConeAngle.setText( FreeCAD.Units.Quantity(obj.HelixConeAngle, FreeCAD.Units.Angle).UserString ) - self.form.HelixDiameterLimit.setProperty("rawValue", obj.HelixDiameterLimit.Value) + self.form.HelixMaxDiameterPercent.setValue(obj.HelixMaxDiameterPercent) + self.form.HelixMinDiameterPercent.setValue(obj.HelixMinDiameterPercent) self.form.LiftDistance.setProperty("rawValue", obj.LiftDistance.Value) @@ -124,10 +128,16 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): if obj.StepOver != self.form.stepOverPercent.value(): obj.StepOver = self.form.stepOverPercent.value() + if obj.HelixMaxDiameterPercent != self.form.HelixMaxDiameterPercent.value(): + obj.HelixMaxDiameterPercent = self.form.HelixMaxDiameterPercent.value() + + if obj.HelixMinDiameterPercent != self.form.HelixMinDiameterPercent.value(): + obj.HelixMinDiameterPercent = self.form.HelixMinDiameterPercent.value() + obj.Tolerance = 1.0 * self.form.Tolerance.value() / 100.0 PathGuiUtil.updateInputField(obj, "HelixAngle", self.form.HelixAngle) + PathGuiUtil.updateInputField(obj, "HelixMaxStepdown", self.form.HelixMaxStepdown) PathGuiUtil.updateInputField(obj, "HelixConeAngle", self.form.HelixConeAngle) - PathGuiUtil.updateInputField(obj, "HelixDiameterLimit", self.form.HelixDiameterLimit) PathGuiUtil.updateInputField(obj, "LiftDistance", self.form.LiftDistance) if hasattr(obj, "KeepToolDownRatio"): diff --git a/src/Mod/CAM/libarea/Adaptive.cpp b/src/Mod/CAM/libarea/Adaptive.cpp index 5a3015a190..d0a52c477d 100644 --- a/src/Mod/CAM/libarea/Adaptive.cpp +++ b/src/Mod/CAM/libarea/Adaptive.cpp @@ -1773,17 +1773,15 @@ std::list Adaptive2d::Execute( lastProgressTime = clock(); stopProcessing = false; - if (helixRampDiameter < NTOL) { - helixRampDiameter = 0.75 * toolDiameter; - } - if (helixRampDiameter > toolDiameter) { - helixRampDiameter = toolDiameter; - } - if (helixRampDiameter < toolDiameter / 8) { - helixRampDiameter = toolDiameter / 8; + if (helixRampTargetDiameter < NTOL) { + helixRampTargetDiameter = toolDiameter; } + helixRampTargetDiameter = min(helixRampTargetDiameter, toolDiameter); + helixRampMinDiameter = max(helixRampMinDiameter, toolDiameter / 8); + helixRampTargetDiameter = max(helixRampTargetDiameter, helixRampMinDiameter); - helixRampRadiusScaled = long(helixRampDiameter * scaleFactor / 2); + helixRampMaxRadiusScaled = long(helixRampTargetDiameter * scaleFactor / 2); + helixRampMinRadiusScaled = long(helixRampMinDiameter * scaleFactor / 2); if (finishingProfile) { finishPassOffsetScaled = long(stepOverScaled / 10); } @@ -1812,7 +1810,7 @@ std::list Adaptive2d::Execute( #ifdef DEV_MODE cout << "optimalCutAreaPD:" << optimalCutAreaPD << " scaleFactor:" << scaleFactor << " toolRadiusScaled:" << toolRadiusScaled - << " helixRampRadiusScaled:" << helixRampRadiusScaled << endl; + << " helixRampMaxRadiusScaled:" << helixRampMaxRadiusScaled << endl; #endif //****************************** // Convert input paths to clipper @@ -1912,8 +1910,8 @@ std::list Adaptive2d::Execute( if (opType == OperationType::otProfilingInside || opType == OperationType::otProfilingOutside) { double offset = opType == OperationType::otProfilingInside - ? -2 * (helixRampRadiusScaled + toolRadiusScaled) - MIN_STEP_CLIPPER - : 2 * (helixRampRadiusScaled + toolRadiusScaled) + MIN_STEP_CLIPPER; + ? -2 * (helixRampMaxRadiusScaled + toolRadiusScaled) - MIN_STEP_CLIPPER + : 2 * (helixRampMaxRadiusScaled + toolRadiusScaled) + MIN_STEP_CLIPPER; for (const auto& current : inputPaths) { int nesting = getPathNestingLevel(current, inputPaths); if (nesting % 2 != 0 && (polyTreeNestingLimit == 0 || nesting <= polyTreeNestingLimit)) { @@ -1977,7 +1975,8 @@ bool Adaptive2d::FindEntryPoint( ClearedArea& clearedArea /*output-initial cleared area by helix*/, IntPoint& entryPoint /*output*/, IntPoint& toolPos, - DoublePoint& toolDir + DoublePoint& toolDir, + long& helixRadiusScaled ) { Paths incOffset; @@ -2018,13 +2017,12 @@ bool Adaptive2d::FindEntryPoint( } } // check if helix fits - if (found) { - // make initial polygon cleared by helix ramp + const auto checkHelixFit = [&](long testHelixRadiusScaled) { clipof.Clear(); Path p1; p1.push_back(entryPoint); clipof.AddPath(p1, JoinType::jtRound, EndType::etOpenRound); - clipof.Execute(clearedPaths, helixRampRadiusScaled + toolRadiusScaled); + clipof.Execute(clearedPaths, (double)(testHelixRadiusScaled + toolRadiusScaled)); CleanPolygons(clearedPaths); // we got first cleared area - check if it is crossing boundary clip.Clear(); @@ -2032,11 +2030,32 @@ bool Adaptive2d::FindEntryPoint( clip.AddPaths(boundPaths, PolyType::ptClip, true); Paths crossing; clip.Execute(ClipType::ctDifference, crossing); - if (!crossing.empty()) { - // helix does not fit to the cutting area + + return crossing.empty(); + }; + + if (found) { + // check that helix fits, and make initial polygon cleared by helix ramp + if (!checkHelixFit(helixRampMinRadiusScaled)) { + // min-size helix does not fit found = false; } else { + // find the largest helix that fits + // minSize = largest known fit; maxSize = largest possible fit + long minSize = helixRampMinRadiusScaled; + long maxSize = helixRampMaxRadiusScaled; + while (minSize < maxSize) { + long testSize = (minSize + maxSize + 1) / 2; // always testSize > minSize + if (checkHelixFit(testSize)) { + minSize = testSize; + } + else { + maxSize = testSize - 1; // always maxSize >= minSize + } + } + helixRadiusScaled = minSize; + checkHelixFit(helixRadiusScaled); // set clearedPaths for final size clearedArea.SetClearedPaths(clearedPaths); } } @@ -2070,14 +2089,15 @@ bool Adaptive2d::FindEntryPoint( hp << entryPoint; clipof.AddPath(hp, JoinType::jtRound, EndType::etOpenRound); Paths hps; - clipof.Execute(hps, helixRampRadiusScaled); + clipof.Execute(hps, helixRadiusScaled); AddPathsToProgress(progressPaths, hps); - toolPos = IntPoint(entryPoint.X, entryPoint.Y - helixRampRadiusScaled); + toolPos = IntPoint(entryPoint.X, entryPoint.Y - helixRadiusScaled); toolDir = DoublePoint(1.0, 0.0); } return found; } + bool Adaptive2d::FindEntryPointOutside( TPaths& progressPaths, const Paths& toolBoundPaths, @@ -2780,6 +2800,7 @@ void Adaptive2d::ProcessPolyNode(Paths boundPaths, Paths toolBoundPaths) ClipperOffset clipof; IntPoint entryPoint; + long helixRadiusScaled; TPaths progressPaths; progressPaths.reserve(10000); @@ -2824,7 +2845,16 @@ void Adaptive2d::ProcessPolyNode(Paths boundPaths, Paths toolBoundPaths) outsideEntry = true; } else { - if (!FindEntryPoint(progressPaths, toolBoundPaths, boundPaths, cleared, entryPoint, toolPos, toolDir)) { + if (!FindEntryPoint( + progressPaths, + toolBoundPaths, + boundPaths, + cleared, + entryPoint, + toolPos, + toolDir, + helixRadiusScaled + )) { Perf_ProcessPolyNode.Stop(); return; } diff --git a/src/Mod/CAM/libarea/Adaptive.hpp b/src/Mod/CAM/libarea/Adaptive.hpp index 03b63ad270..4c0690eab8 100644 --- a/src/Mod/CAM/libarea/Adaptive.hpp +++ b/src/Mod/CAM/libarea/Adaptive.hpp @@ -87,7 +87,8 @@ class Adaptive2d public: Adaptive2d(); double toolDiameter = 5; - double helixRampDiameter = 0; + double helixRampTargetDiameter = 0; + double helixRampMinDiameter = 0; double stepOverFactor = 0.2; double tolerance = 0.1; double stockToLeave = 0; @@ -118,7 +119,8 @@ private: double stepOverScaled = 1; long toolRadiusScaled = 10; long finishPassOffsetScaled = 0; - long helixRampRadiusScaled = 0; + long helixRampMaxRadiusScaled = 0; + long helixRampMinRadiusScaled = 0; double referenceCutArea = 0; double optimalCutAreaPD = 0; bool stopProcessing = false; @@ -136,7 +138,8 @@ private: ClearedArea& cleared /*output*/, IntPoint& entryPoint /*output*/, IntPoint& toolPos, - DoublePoint& toolDir + DoublePoint& toolDir, + long& helixRadiusScaled ); bool FindEntryPointOutside( TPaths& progressPaths, diff --git a/src/Mod/CAM/libarea/pyarea.cpp b/src/Mod/CAM/libarea/pyarea.cpp index ee3cfd483b..5cecf5c1b3 100644 --- a/src/Mod/CAM/libarea/pyarea.cpp +++ b/src/Mod/CAM/libarea/pyarea.cpp @@ -426,7 +426,8 @@ void init_pyarea(py::module& m) .def_readwrite("stepOverFactor", &Adaptive2d::stepOverFactor) .def_readwrite("toolDiameter", &Adaptive2d::toolDiameter) .def_readwrite("stockToLeave", &Adaptive2d::stockToLeave) - .def_readwrite("helixRampDiameter", &Adaptive2d::helixRampDiameter) + .def_readwrite("helixRampTargetDiameter", &Adaptive2d::helixRampTargetDiameter) + .def_readwrite("helixRampMinDiameter", &Adaptive2d::helixRampMinDiameter) .def_readwrite("forceInsideOut", &Adaptive2d::forceInsideOut) .def_readwrite("finishingProfile", &Adaptive2d::finishingProfile) //.def_readwrite("polyTreeNestingLimit", &Adaptive2d::polyTreeNestingLimit)