From 43c279702d208e5562d64c80c3802aa81b12ff5e Mon Sep 17 00:00:00 2001 From: Bryan Bendall Date: Fri, 18 Dec 2020 08:02:48 -0500 Subject: [PATCH 1/2] Path: Added option for the finishing pass of the adaptive op --- src/Mod/Path/PathScripts/PathAdaptive.py | 4 + src/Mod/Path/PathScripts/PathAdaptiveGui.py | 8 + src/Mod/Path/libarea/Adaptive.cpp | 180 ++++++++++---------- src/Mod/Path/libarea/Adaptive.hpp | 1 + src/Mod/Path/libarea/PythonStuff.cpp | 1 + 5 files changed, 100 insertions(+), 94 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathAdaptive.py b/src/Mod/Path/PathScripts/PathAdaptive.py index c1b432f908..ff44082ca9 100644 --- a/src/Mod/Path/PathScripts/PathAdaptive.py +++ b/src/Mod/Path/PathScripts/PathAdaptive.py @@ -395,6 +395,7 @@ def Execute(op,obj): "operationType": obj.OperationType, "side": obj.Side, "forceInsideOut" : obj.ForceInsideOut, + "finishingProfile" : obj.FinishingProfile, "keepToolDownRatio": keepToolDownRatio, "stockToLeave": float(obj.StockToLeave) } @@ -433,6 +434,7 @@ def Execute(op,obj): a2d.stockToLeave =float(obj.StockToLeave) a2d.tolerance = float(obj.Tolerance) a2d.forceInsideOut = obj.ForceInsideOut + a2d.finishingProfile = obj.FinishingProfile a2d.opType = opType # EXECUTE @@ -489,6 +491,7 @@ class PathAdaptive(PathOp.ObjectOp): # obj.addProperty("App::PropertyBool", "ProcessHoles", "Adaptive","Process holes as well as the face outline") obj.addProperty("App::PropertyBool", "ForceInsideOut", "Adaptive","Force plunging into material inside and clearing towards the edges") + obj.addProperty("App::PropertyBool", "FinishingProfile", "Adaptive","To take a finishing profile path at the end") obj.addProperty("App::PropertyBool", "Stopped", "Adaptive", "Stop processing") obj.setEditorMode('Stopped', 2) #hide this property @@ -517,6 +520,7 @@ class PathAdaptive(PathOp.ObjectOp): obj.LiftDistance=0 # obj.ProcessHoles = True obj.ForceInsideOut = False + obj.FinishingProfile = True obj.Stopped = False obj.StopProcessing = False obj.HelixAngle = 5 diff --git a/src/Mod/Path/PathScripts/PathAdaptiveGui.py b/src/Mod/Path/PathScripts/PathAdaptiveGui.py index 25bc29f406..e8c6d8da3f 100644 --- a/src/Mod/Path/PathScripts/PathAdaptiveGui.py +++ b/src/Mod/Path/PathScripts/PathAdaptiveGui.py @@ -126,6 +126,11 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): form.ForceInsideOut.setChecked(True) formLayout.addRow(QtGui.QLabel("Force Clearing Inside-Out"), form.ForceInsideOut) + # Finishing profile + form.FinishingProfile = QtGui.QCheckBox() + form.FinishingProfile.setChecked(True) + formLayout.addRow(QtGui.QLabel("Finishing Profile"), form.FinishingProfile) + layout.addLayout(formLayout) # stop button @@ -154,6 +159,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): # signals.append(self.form.ProcessHoles.stateChanged) signals.append(self.form.ForceInsideOut.stateChanged) + signals.append(self.form.FinishingProfile.stateChanged) signals.append(self.form.StopButton.toggled) return signals @@ -173,6 +179,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): # self.form.ProcessHoles.setChecked(obj.ProcessHoles) self.form.ForceInsideOut.setChecked(obj.ForceInsideOut) + self.form.FinishingProfile.setChecked(obj.FinishingProfile) self.setupToolController(obj, self.form.ToolController) self.setupCoolant(obj, self.form.coolantController) self.form.StopButton.setChecked(obj.Stopped) @@ -201,6 +208,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): obj.StockToLeave = self.form.StockToLeave.value() obj.ForceInsideOut = self.form.ForceInsideOut.isChecked() + obj.FinishingProfile = self.form.FinishingProfile.isChecked() obj.Stopped = self.form.StopButton.isChecked() if(obj.Stopped): self.form.StopButton.setChecked(False) # reset the button diff --git a/src/Mod/Path/libarea/Adaptive.cpp b/src/Mod/Path/libarea/Adaptive.cpp index 0dc5fa8a9a..01b91cb4e9 100644 --- a/src/Mod/Path/libarea/Adaptive.cpp +++ b/src/Mod/Path/libarea/Adaptive.cpp @@ -1706,7 +1706,8 @@ std::list Adaptive2d::Execute(const DPaths &stockPaths, const DP helixRampDiameter = toolDiameter / 8; helixRampRadiusScaled = long(helixRampDiameter * scaleFactor / 2); - finishPassOffsetScaled = long(stepOverScaled / 10); + if(finishingProfile) + finishPassOffsetScaled = long(stepOverScaled / 10); ClipperOffset clipof; Clipper clip; @@ -3024,121 +3025,112 @@ void Adaptive2d::ProcessPolyNode(Paths boundPaths, Paths toolBoundPaths) //********************************** //* FINISHING PASS * //********************************** + if(finishingProfile) { + Paths finishingPaths; + clipof.Clear(); + clipof.AddPaths(boundPaths, JoinType::jtRound, EndType::etClosedPolygon); + clipof.Execute(finishingPaths, -toolRadiusScaled); - Paths finishingPaths; - clipof.Clear(); - clipof.AddPaths(boundPaths, JoinType::jtRound, EndType::etClosedPolygon); - clipof.Execute(finishingPaths, -toolRadiusScaled); + clipof.Clear(); + clipof.AddPaths(finishingPaths, JoinType::jtRound, EndType::etClosedPolygon); + clipof.Execute(toolBoundPaths, -1); - clipof.Clear(); - clipof.AddPaths(finishingPaths, JoinType::jtRound, EndType::etClosedPolygon); - clipof.Execute(toolBoundPaths, -1); + IntPoint lastPoint = toolPos; + Path finShiftedPath; - IntPoint lastPoint = toolPos; - Path finShiftedPath; + bool allCutsAllowed = true; + while(!stopProcessing && PopPathWithClosestPoint(finishingPaths, lastPoint, finShiftedPath)) { + if(finShiftedPath.empty()) + continue; + // skip finishing passes outside the stock boundary - no sense to cut where is no material + bool allPointsOutside = true; + IntPoint p1 = finShiftedPath.front(); + for(const auto& pt : finShiftedPath) { - bool allCutsAllowed = true; - while (!stopProcessing && PopPathWithClosestPoint(finishingPaths, lastPoint, finShiftedPath)) - { - if (finShiftedPath.empty()) - continue; - // skip finishing passes outside the stock boundary - no sense to cut where is no material - bool allPointsOutside = true; - IntPoint p1 = finShiftedPath.front(); - for (const auto &pt : finShiftedPath) - { + // midpoint + if(IsPointWithinCutRegion(stockInputPaths, IntPoint((p1.X + pt.X) / 2, (p1.Y + pt.Y) / 2))) { + allPointsOutside = false; + break; + } + //current point + if(IsPointWithinCutRegion(stockInputPaths, pt)) { + allPointsOutside = false; + break; + } - // midpoint - if (IsPointWithinCutRegion(stockInputPaths, IntPoint((p1.X + pt.X) / 2, (p1.Y + pt.Y) / 2))) - { - allPointsOutside = false; - break; + p1 = pt; } - //current point - if (IsPointWithinCutRegion(stockInputPaths, pt)) - { - allPointsOutside = false; - break; + if(allPointsOutside) + continue; + + progressPaths.push_back(TPath()); + // show in progress cb + for(auto& pt : finShiftedPath) { + progressPaths.back().second.emplace_back(double(pt.X) / scaleFactor, double(pt.Y) / scaleFactor); } - p1 = pt; - } - if (allPointsOutside) - continue; + if(!finShiftedPath.empty()) + finShiftedPath << finShiftedPath.front(); // make sure its closed - progressPaths.push_back(TPath()); - // show in progress cb - for (auto &pt : finShiftedPath) - { - progressPaths.back().second.emplace_back(double(pt.X) / scaleFactor, double(pt.Y) / scaleFactor); - } + Path finCleaned; + CleanPath(finShiftedPath, finCleaned, FINISHING_CLEAN_PATH_TOLERANCE); - if (!finShiftedPath.empty()) - finShiftedPath << finShiftedPath.front(); // make sure its closed + // sanity check for finishing paths - check the area of finishing cut + for(size_t i = 1; i < finCleaned.size(); i++) { + if(!IsAllowedToCutTrough(finCleaned.at(i - 1), finCleaned.at(i), cleared, toolBoundPaths, 2.0, true)) { + allCutsAllowed = false; + } + } - Path finCleaned; - CleanPath(finShiftedPath, finCleaned, FINISHING_CLEAN_PATH_TOLERANCE); + // make sure it's closed + finCleaned.push_back(finCleaned.front()); + AppendToolPath(progressPaths, output, finCleaned, cleared, cleared, toolBoundPaths); - // sanity check for finishing paths - check the area of finishing cut - for (size_t i = 1; i < finCleaned.size(); i++) - { - if (!IsAllowedToCutTrough(finCleaned.at(i - 1), finCleaned.at(i), cleared, toolBoundPaths, 2.0, true)) - { - allCutsAllowed = false; + cleared.ExpandCleared(finCleaned); + + if(!finCleaned.empty()) { + lastPoint.X = finCleaned.back().X; + lastPoint.Y = finCleaned.back().Y; } } - // make sure it's closed - finCleaned.push_back(finCleaned.front()); - AppendToolPath(progressPaths, output, finCleaned, cleared, cleared, toolBoundPaths); + Path returnPath; + returnPath << lastPoint; + returnPath << entryPoint; + output.ReturnMotionType = IsClearPath(returnPath, cleared) ? MotionType::mtLinkClear : MotionType::mtLinkNotClear; - cleared.ExpandCleared(finCleaned); - - if (!finCleaned.empty()) - { - lastPoint.X = finCleaned.back().X; - lastPoint.Y = finCleaned.back().Y; - } - } - - Path returnPath; - returnPath << lastPoint; - returnPath << entryPoint; - output.ReturnMotionType = IsClearPath(returnPath, cleared) ? MotionType::mtLinkClear : MotionType::mtLinkNotClear; - -// dump performance results + // dump performance results #ifdef DEV_MODE - Perf_ProcessPolyNode.Stop(); - Perf_ProcessPolyNode.DumpResults(); - Perf_PointIterations.DumpResults(); - Perf_CalcCutAreaCirc.DumpResults(); - Perf_CalcCutAreaClip.DumpResults(); - Perf_NextEngagePoint.DumpResults(); - Perf_ExpandCleared.DumpResults(); - Perf_DistanceToBoundary.DumpResults(); - Perf_AppendToolPath.DumpResults(); - Perf_IsAllowedToCutTrough.DumpResults(); - Perf_IsClearPath.DumpResults(); + Perf_ProcessPolyNode.Stop(); + Perf_ProcessPolyNode.DumpResults(); + Perf_PointIterations.DumpResults(); + Perf_CalcCutAreaCirc.DumpResults(); + Perf_CalcCutAreaClip.DumpResults(); + Perf_NextEngagePoint.DumpResults(); + Perf_ExpandCleared.DumpResults(); + Perf_DistanceToBoundary.DumpResults(); + Perf_AppendToolPath.DumpResults(); + Perf_IsAllowedToCutTrough.DumpResults(); + Perf_IsClearPath.DumpResults(); #endif - CheckReportProgress(progressPaths, true); + CheckReportProgress(progressPaths, true); #ifdef DEV_MODE - double duration = ((double)(clock() - start_clock)) / CLOCKS_PER_SEC; - cout << "PolyNode perf:" << perf_total_len / double(scaleFactor) / duration << " mm/sec" - << " processed_points:" << total_points - << " output_points:" << total_output_points - << " total_iterations:" << total_iterations - << " iter_per_point:" << (double(total_iterations) / ((double(total_points) + 0.001))) - << " total_exceeded:" << total_exceeded << " (" << 100 * double(total_exceeded) / double(total_points) << "%)" - << endl; + double duration = ((double) (clock() - start_clock)) / CLOCKS_PER_SEC; + cout << "PolyNode perf:" << perf_total_len / double(scaleFactor) / duration << " mm/sec" + << " processed_points:" << total_points + << " output_points:" << total_output_points + << " total_iterations:" << total_iterations + << " iter_per_point:" << (double(total_iterations) / ((double(total_points) + 0.001))) + << " total_exceeded:" << total_exceeded << " (" << 100 * double(total_exceeded) / double(total_points) << "%)" + << endl; #endif - // warn about invalid paths being detected - if (!allCutsAllowed) - { - cerr << "Warning: some cuts may be above optimal step-over. Please double check the results." << endl - << "Hint: try to modify accuracy and/or step-over." << endl; + // warn about invalid paths being detected + if(!allCutsAllowed) { + cerr << "Warning: some cuts may be above optimal step-over. Please double check the results." << endl + << "Hint: try to modify accuracy and/or step-over." << endl; + } } - results.push_back(output); } diff --git a/src/Mod/Path/libarea/Adaptive.hpp b/src/Mod/Path/libarea/Adaptive.hpp index 7b15e006ad..e0e9ad04ab 100644 --- a/src/Mod/Path/libarea/Adaptive.hpp +++ b/src/Mod/Path/libarea/Adaptive.hpp @@ -93,6 +93,7 @@ class Adaptive2d double tolerance = 0.1; double stockToLeave = 0; bool forceInsideOut = true; + bool finishingProfile = true; double keepToolDownDistRatio = 3.0; // keep tool down distance ratio OperationType opType = OperationType::otClearingInside; diff --git a/src/Mod/Path/libarea/PythonStuff.cpp b/src/Mod/Path/libarea/PythonStuff.cpp index 7f58e8eead..9f531086de 100644 --- a/src/Mod/Path/libarea/PythonStuff.cpp +++ b/src/Mod/Path/libarea/PythonStuff.cpp @@ -532,6 +532,7 @@ BOOST_PYTHON_MODULE(area) { .def_readwrite("stockToLeave", &Adaptive2d::stockToLeave) .def_readwrite("helixRampDiameter", &Adaptive2d::helixRampDiameter) .def_readwrite("forceInsideOut", &Adaptive2d::forceInsideOut) + .def_readwrite("finishingProfile", &Adaptive2d::finishingProfile) //.def_readwrite("polyTreeNestingLimit", &Adaptive2d::polyTreeNestingLimit) .def_readwrite("tolerance", &Adaptive2d::tolerance) .def_readwrite("keepToolDownDistRatio", &Adaptive2d::keepToolDownDistRatio) From d6cd6f288f5baa941dad7f2add45765025b0f483 Mon Sep 17 00:00:00 2001 From: Bryan Bendall Date: Fri, 18 Dec 2020 08:02:48 -0500 Subject: [PATCH 2/2] Path: Added option for the finishing pass of the adaptive op --- src/Mod/Path/PathScripts/PathAdaptive.py | 4 + src/Mod/Path/PathScripts/PathAdaptiveGui.py | 8 + src/Mod/Path/libarea/Adaptive.cpp | 180 ++++++++++---------- src/Mod/Path/libarea/Adaptive.hpp | 1 + src/Mod/Path/libarea/PythonStuff.cpp | 1 + 5 files changed, 100 insertions(+), 94 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathAdaptive.py b/src/Mod/Path/PathScripts/PathAdaptive.py index c1b432f908..ff44082ca9 100644 --- a/src/Mod/Path/PathScripts/PathAdaptive.py +++ b/src/Mod/Path/PathScripts/PathAdaptive.py @@ -395,6 +395,7 @@ def Execute(op,obj): "operationType": obj.OperationType, "side": obj.Side, "forceInsideOut" : obj.ForceInsideOut, + "finishingProfile" : obj.FinishingProfile, "keepToolDownRatio": keepToolDownRatio, "stockToLeave": float(obj.StockToLeave) } @@ -433,6 +434,7 @@ def Execute(op,obj): a2d.stockToLeave =float(obj.StockToLeave) a2d.tolerance = float(obj.Tolerance) a2d.forceInsideOut = obj.ForceInsideOut + a2d.finishingProfile = obj.FinishingProfile a2d.opType = opType # EXECUTE @@ -489,6 +491,7 @@ class PathAdaptive(PathOp.ObjectOp): # obj.addProperty("App::PropertyBool", "ProcessHoles", "Adaptive","Process holes as well as the face outline") obj.addProperty("App::PropertyBool", "ForceInsideOut", "Adaptive","Force plunging into material inside and clearing towards the edges") + obj.addProperty("App::PropertyBool", "FinishingProfile", "Adaptive","To take a finishing profile path at the end") obj.addProperty("App::PropertyBool", "Stopped", "Adaptive", "Stop processing") obj.setEditorMode('Stopped', 2) #hide this property @@ -517,6 +520,7 @@ class PathAdaptive(PathOp.ObjectOp): obj.LiftDistance=0 # obj.ProcessHoles = True obj.ForceInsideOut = False + obj.FinishingProfile = True obj.Stopped = False obj.StopProcessing = False obj.HelixAngle = 5 diff --git a/src/Mod/Path/PathScripts/PathAdaptiveGui.py b/src/Mod/Path/PathScripts/PathAdaptiveGui.py index 25bc29f406..e8c6d8da3f 100644 --- a/src/Mod/Path/PathScripts/PathAdaptiveGui.py +++ b/src/Mod/Path/PathScripts/PathAdaptiveGui.py @@ -126,6 +126,11 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): form.ForceInsideOut.setChecked(True) formLayout.addRow(QtGui.QLabel("Force Clearing Inside-Out"), form.ForceInsideOut) + # Finishing profile + form.FinishingProfile = QtGui.QCheckBox() + form.FinishingProfile.setChecked(True) + formLayout.addRow(QtGui.QLabel("Finishing Profile"), form.FinishingProfile) + layout.addLayout(formLayout) # stop button @@ -154,6 +159,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): # signals.append(self.form.ProcessHoles.stateChanged) signals.append(self.form.ForceInsideOut.stateChanged) + signals.append(self.form.FinishingProfile.stateChanged) signals.append(self.form.StopButton.toggled) return signals @@ -173,6 +179,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): # self.form.ProcessHoles.setChecked(obj.ProcessHoles) self.form.ForceInsideOut.setChecked(obj.ForceInsideOut) + self.form.FinishingProfile.setChecked(obj.FinishingProfile) self.setupToolController(obj, self.form.ToolController) self.setupCoolant(obj, self.form.coolantController) self.form.StopButton.setChecked(obj.Stopped) @@ -201,6 +208,7 @@ class TaskPanelOpPage(PathOpGui.TaskPanelPage): obj.StockToLeave = self.form.StockToLeave.value() obj.ForceInsideOut = self.form.ForceInsideOut.isChecked() + obj.FinishingProfile = self.form.FinishingProfile.isChecked() obj.Stopped = self.form.StopButton.isChecked() if(obj.Stopped): self.form.StopButton.setChecked(False) # reset the button diff --git a/src/Mod/Path/libarea/Adaptive.cpp b/src/Mod/Path/libarea/Adaptive.cpp index 0dc5fa8a9a..01b91cb4e9 100644 --- a/src/Mod/Path/libarea/Adaptive.cpp +++ b/src/Mod/Path/libarea/Adaptive.cpp @@ -1706,7 +1706,8 @@ std::list Adaptive2d::Execute(const DPaths &stockPaths, const DP helixRampDiameter = toolDiameter / 8; helixRampRadiusScaled = long(helixRampDiameter * scaleFactor / 2); - finishPassOffsetScaled = long(stepOverScaled / 10); + if(finishingProfile) + finishPassOffsetScaled = long(stepOverScaled / 10); ClipperOffset clipof; Clipper clip; @@ -3024,121 +3025,112 @@ void Adaptive2d::ProcessPolyNode(Paths boundPaths, Paths toolBoundPaths) //********************************** //* FINISHING PASS * //********************************** + if(finishingProfile) { + Paths finishingPaths; + clipof.Clear(); + clipof.AddPaths(boundPaths, JoinType::jtRound, EndType::etClosedPolygon); + clipof.Execute(finishingPaths, -toolRadiusScaled); - Paths finishingPaths; - clipof.Clear(); - clipof.AddPaths(boundPaths, JoinType::jtRound, EndType::etClosedPolygon); - clipof.Execute(finishingPaths, -toolRadiusScaled); + clipof.Clear(); + clipof.AddPaths(finishingPaths, JoinType::jtRound, EndType::etClosedPolygon); + clipof.Execute(toolBoundPaths, -1); - clipof.Clear(); - clipof.AddPaths(finishingPaths, JoinType::jtRound, EndType::etClosedPolygon); - clipof.Execute(toolBoundPaths, -1); + IntPoint lastPoint = toolPos; + Path finShiftedPath; - IntPoint lastPoint = toolPos; - Path finShiftedPath; + bool allCutsAllowed = true; + while(!stopProcessing && PopPathWithClosestPoint(finishingPaths, lastPoint, finShiftedPath)) { + if(finShiftedPath.empty()) + continue; + // skip finishing passes outside the stock boundary - no sense to cut where is no material + bool allPointsOutside = true; + IntPoint p1 = finShiftedPath.front(); + for(const auto& pt : finShiftedPath) { - bool allCutsAllowed = true; - while (!stopProcessing && PopPathWithClosestPoint(finishingPaths, lastPoint, finShiftedPath)) - { - if (finShiftedPath.empty()) - continue; - // skip finishing passes outside the stock boundary - no sense to cut where is no material - bool allPointsOutside = true; - IntPoint p1 = finShiftedPath.front(); - for (const auto &pt : finShiftedPath) - { + // midpoint + if(IsPointWithinCutRegion(stockInputPaths, IntPoint((p1.X + pt.X) / 2, (p1.Y + pt.Y) / 2))) { + allPointsOutside = false; + break; + } + //current point + if(IsPointWithinCutRegion(stockInputPaths, pt)) { + allPointsOutside = false; + break; + } - // midpoint - if (IsPointWithinCutRegion(stockInputPaths, IntPoint((p1.X + pt.X) / 2, (p1.Y + pt.Y) / 2))) - { - allPointsOutside = false; - break; + p1 = pt; } - //current point - if (IsPointWithinCutRegion(stockInputPaths, pt)) - { - allPointsOutside = false; - break; + if(allPointsOutside) + continue; + + progressPaths.push_back(TPath()); + // show in progress cb + for(auto& pt : finShiftedPath) { + progressPaths.back().second.emplace_back(double(pt.X) / scaleFactor, double(pt.Y) / scaleFactor); } - p1 = pt; - } - if (allPointsOutside) - continue; + if(!finShiftedPath.empty()) + finShiftedPath << finShiftedPath.front(); // make sure its closed - progressPaths.push_back(TPath()); - // show in progress cb - for (auto &pt : finShiftedPath) - { - progressPaths.back().second.emplace_back(double(pt.X) / scaleFactor, double(pt.Y) / scaleFactor); - } + Path finCleaned; + CleanPath(finShiftedPath, finCleaned, FINISHING_CLEAN_PATH_TOLERANCE); - if (!finShiftedPath.empty()) - finShiftedPath << finShiftedPath.front(); // make sure its closed + // sanity check for finishing paths - check the area of finishing cut + for(size_t i = 1; i < finCleaned.size(); i++) { + if(!IsAllowedToCutTrough(finCleaned.at(i - 1), finCleaned.at(i), cleared, toolBoundPaths, 2.0, true)) { + allCutsAllowed = false; + } + } - Path finCleaned; - CleanPath(finShiftedPath, finCleaned, FINISHING_CLEAN_PATH_TOLERANCE); + // make sure it's closed + finCleaned.push_back(finCleaned.front()); + AppendToolPath(progressPaths, output, finCleaned, cleared, cleared, toolBoundPaths); - // sanity check for finishing paths - check the area of finishing cut - for (size_t i = 1; i < finCleaned.size(); i++) - { - if (!IsAllowedToCutTrough(finCleaned.at(i - 1), finCleaned.at(i), cleared, toolBoundPaths, 2.0, true)) - { - allCutsAllowed = false; + cleared.ExpandCleared(finCleaned); + + if(!finCleaned.empty()) { + lastPoint.X = finCleaned.back().X; + lastPoint.Y = finCleaned.back().Y; } } - // make sure it's closed - finCleaned.push_back(finCleaned.front()); - AppendToolPath(progressPaths, output, finCleaned, cleared, cleared, toolBoundPaths); + Path returnPath; + returnPath << lastPoint; + returnPath << entryPoint; + output.ReturnMotionType = IsClearPath(returnPath, cleared) ? MotionType::mtLinkClear : MotionType::mtLinkNotClear; - cleared.ExpandCleared(finCleaned); - - if (!finCleaned.empty()) - { - lastPoint.X = finCleaned.back().X; - lastPoint.Y = finCleaned.back().Y; - } - } - - Path returnPath; - returnPath << lastPoint; - returnPath << entryPoint; - output.ReturnMotionType = IsClearPath(returnPath, cleared) ? MotionType::mtLinkClear : MotionType::mtLinkNotClear; - -// dump performance results + // dump performance results #ifdef DEV_MODE - Perf_ProcessPolyNode.Stop(); - Perf_ProcessPolyNode.DumpResults(); - Perf_PointIterations.DumpResults(); - Perf_CalcCutAreaCirc.DumpResults(); - Perf_CalcCutAreaClip.DumpResults(); - Perf_NextEngagePoint.DumpResults(); - Perf_ExpandCleared.DumpResults(); - Perf_DistanceToBoundary.DumpResults(); - Perf_AppendToolPath.DumpResults(); - Perf_IsAllowedToCutTrough.DumpResults(); - Perf_IsClearPath.DumpResults(); + Perf_ProcessPolyNode.Stop(); + Perf_ProcessPolyNode.DumpResults(); + Perf_PointIterations.DumpResults(); + Perf_CalcCutAreaCirc.DumpResults(); + Perf_CalcCutAreaClip.DumpResults(); + Perf_NextEngagePoint.DumpResults(); + Perf_ExpandCleared.DumpResults(); + Perf_DistanceToBoundary.DumpResults(); + Perf_AppendToolPath.DumpResults(); + Perf_IsAllowedToCutTrough.DumpResults(); + Perf_IsClearPath.DumpResults(); #endif - CheckReportProgress(progressPaths, true); + CheckReportProgress(progressPaths, true); #ifdef DEV_MODE - double duration = ((double)(clock() - start_clock)) / CLOCKS_PER_SEC; - cout << "PolyNode perf:" << perf_total_len / double(scaleFactor) / duration << " mm/sec" - << " processed_points:" << total_points - << " output_points:" << total_output_points - << " total_iterations:" << total_iterations - << " iter_per_point:" << (double(total_iterations) / ((double(total_points) + 0.001))) - << " total_exceeded:" << total_exceeded << " (" << 100 * double(total_exceeded) / double(total_points) << "%)" - << endl; + double duration = ((double) (clock() - start_clock)) / CLOCKS_PER_SEC; + cout << "PolyNode perf:" << perf_total_len / double(scaleFactor) / duration << " mm/sec" + << " processed_points:" << total_points + << " output_points:" << total_output_points + << " total_iterations:" << total_iterations + << " iter_per_point:" << (double(total_iterations) / ((double(total_points) + 0.001))) + << " total_exceeded:" << total_exceeded << " (" << 100 * double(total_exceeded) / double(total_points) << "%)" + << endl; #endif - // warn about invalid paths being detected - if (!allCutsAllowed) - { - cerr << "Warning: some cuts may be above optimal step-over. Please double check the results." << endl - << "Hint: try to modify accuracy and/or step-over." << endl; + // warn about invalid paths being detected + if(!allCutsAllowed) { + cerr << "Warning: some cuts may be above optimal step-over. Please double check the results." << endl + << "Hint: try to modify accuracy and/or step-over." << endl; + } } - results.push_back(output); } diff --git a/src/Mod/Path/libarea/Adaptive.hpp b/src/Mod/Path/libarea/Adaptive.hpp index 7b15e006ad..e0e9ad04ab 100644 --- a/src/Mod/Path/libarea/Adaptive.hpp +++ b/src/Mod/Path/libarea/Adaptive.hpp @@ -93,6 +93,7 @@ class Adaptive2d double tolerance = 0.1; double stockToLeave = 0; bool forceInsideOut = true; + bool finishingProfile = true; double keepToolDownDistRatio = 3.0; // keep tool down distance ratio OperationType opType = OperationType::otClearingInside; diff --git a/src/Mod/Path/libarea/PythonStuff.cpp b/src/Mod/Path/libarea/PythonStuff.cpp index 7f58e8eead..9f531086de 100644 --- a/src/Mod/Path/libarea/PythonStuff.cpp +++ b/src/Mod/Path/libarea/PythonStuff.cpp @@ -532,6 +532,7 @@ BOOST_PYTHON_MODULE(area) { .def_readwrite("stockToLeave", &Adaptive2d::stockToLeave) .def_readwrite("helixRampDiameter", &Adaptive2d::helixRampDiameter) .def_readwrite("forceInsideOut", &Adaptive2d::forceInsideOut) + .def_readwrite("finishingProfile", &Adaptive2d::finishingProfile) //.def_readwrite("polyTreeNestingLimit", &Adaptive2d::polyTreeNestingLimit) .def_readwrite("tolerance", &Adaptive2d::tolerance) .def_readwrite("keepToolDownDistRatio", &Adaptive2d::keepToolDownDistRatio)