Path: Added option for the finishing pass of the adaptive op
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1706,7 +1706,8 @@ std::list<AdaptiveOutput> 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user