Skip to content

Commit

Permalink
Path: Added option for the finishing pass of the adaptive op
Browse files Browse the repository at this point in the history
  • Loading branch information
bryanbendall committed Dec 18, 2020
1 parent 8462fc1 commit d6cd6f2
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 94 deletions.
4 changes: 4 additions & 0 deletions src/Mod/Path/PathScripts/PathAdaptive.py
Expand Up @@ -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)
}
Expand Down Expand Up @@ -433,6 +434,7 @@ def progressFn(tpaths):
a2d.stockToLeave =float(obj.StockToLeave)
a2d.tolerance = float(obj.Tolerance)
a2d.forceInsideOut = obj.ForceInsideOut
a2d.finishingProfile = obj.FinishingProfile
a2d.opType = opType

# EXECUTE
Expand Down Expand Up @@ -489,6 +491,7 @@ def initOperation(self, obj):
# 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
Expand Down Expand Up @@ -517,6 +520,7 @@ def opSetDefaultValues(self, obj, job):
obj.LiftDistance=0
# obj.ProcessHoles = True
obj.ForceInsideOut = False
obj.FinishingProfile = True
obj.Stopped = False
obj.StopProcessing = False
obj.HelixAngle = 5
Expand Down
8 changes: 8 additions & 0 deletions src/Mod/Path/PathScripts/PathAdaptiveGui.py
Expand Up @@ -126,6 +126,11 @@ def getForm(self):
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
Expand Down Expand Up @@ -154,6 +159,7 @@ def getSignalsForUpdate(self, obj):

# 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

Expand All @@ -173,6 +179,7 @@ def setFields(self, obj):

# 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)
Expand Down Expand Up @@ -201,6 +208,7 @@ def getFields(self, obj):
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
Expand Down
180 changes: 86 additions & 94 deletions src/Mod/Path/libarea/Adaptive.cpp
Expand Up @@ -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;
Expand Down Expand Up @@ -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();

This comment has been minimized.

Copy link
@sundtek

sundtek Jan 4, 2022

Contributor

Shouldn't this be finShiftedPath.back()?

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;
}

p1 = pt;
}
if (allPointsOutside)
continue;
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);
}
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);
}

if (!finShiftedPath.empty())
finShiftedPath << finShiftedPath.front(); // make sure its closed
if(!finShiftedPath.empty())
finShiftedPath << finShiftedPath.front(); // make sure its closed

Path finCleaned;
CleanPath(finShiftedPath, finCleaned, FINISHING_CLEAN_PATH_TOLERANCE);
Path finCleaned;
CleanPath(finShiftedPath, finCleaned, FINISHING_CLEAN_PATH_TOLERANCE);

// 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;
// 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;
}
}
}

// make sure it's closed
finCleaned.push_back(finCleaned.front());
AppendToolPath(progressPaths, output, finCleaned, cleared, cleared, toolBoundPaths);
// make sure it's closed
finCleaned.push_back(finCleaned.front());
AppendToolPath(progressPaths, output, finCleaned, cleared, cleared, toolBoundPaths);

cleared.ExpandCleared(finCleaned);
cleared.ExpandCleared(finCleaned);

if (!finCleaned.empty())
{
lastPoint.X = finCleaned.back().X;
lastPoint.Y = finCleaned.back().Y;
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;
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);
}

Expand Down
1 change: 1 addition & 0 deletions src/Mod/Path/libarea/Adaptive.hpp
Expand Up @@ -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;

Expand Down
1 change: 1 addition & 0 deletions src/Mod/Path/libarea/PythonStuff.cpp
Expand Up @@ -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)
Expand Down

0 comments on commit d6cd6f2

Please sign in to comment.