From 9d60ced83dbf0007f5105f2b91ffb6f46d117328 Mon Sep 17 00:00:00 2001 From: kreso-t Date: Sun, 28 Oct 2018 20:44:48 +0100 Subject: [PATCH] Path: Adaptive - finishing path improvements - fixed bug in path cleaning (artifacts on the finish path) - increased path discretization resolution --- src/Mod/Path/PathScripts/PathAdaptive.py | 10 ++-- src/Mod/Path/libarea/Adaptive.cpp | 65 +++++++++++++----------- src/Mod/Path/libarea/Adaptive.hpp | 9 ++-- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/src/Mod/Path/PathScripts/PathAdaptive.py b/src/Mod/Path/PathScripts/PathAdaptive.py index e4ea9c46cb..332d38a372 100644 --- a/src/Mod/Path/PathScripts/PathAdaptive.py +++ b/src/Mod/Path/PathScripts/PathAdaptive.py @@ -35,11 +35,6 @@ from pivy import coin __doc__ = "Class and implementation of the Adaptive path operation." -def discretize(edge, flipDirection=False): - pts=edge.discretize(Deflection=0.01) - if flipDirection: pts.reverse() - return pts - def convertTo2d(pathArray): output = [] for path in pathArray: @@ -81,6 +76,11 @@ def sceneClean(): sceneGraph.removeChild(n) del scenePathNodes[:] +def discretize(edge, flipDirection=False): + pts=edge.discretize(Deflection=0.0001) + if flipDirection: pts.reverse() + return pts + def GenerateGCode(op,obj,adaptiveResults, helixDiameter): if len(adaptiveResults)==0 or len(adaptiveResults[0]["AdaptivePaths"])==0: return diff --git a/src/Mod/Path/libarea/Adaptive.cpp b/src/Mod/Path/libarea/Adaptive.cpp index 00db3a6df9..439d2382bc 100644 --- a/src/Mod/Path/libarea/Adaptive.cpp +++ b/src/Mod/Path/libarea/Adaptive.cpp @@ -336,40 +336,41 @@ void ScaleDownPaths(Paths &paths,long scaleFactor) { // joins collinear segments (within the tolerance) -void CleanPath(const Path &inp, Path &outp, double tolerance) +void CleanPath(const Path &inp, Path &outpt, double tolerance) { - outp.clear(); if (inp.size() < 3) { - outp = inp; + outpt = inp; return; } + Path tmp; + CleanPolygon(inp, tmp, tolerance); + // restore starting point - double tolSqrd = tolerance * tolerance; - - IntPoint p1 = inp.at(0); - IntPoint p2 = p1; - outp.push_back(p1); - for (size_t i = 1; i < inp.size(); i++) + Path::size_type size = tmp.size(); + double minDistSq = __DBL_MAX__; + double distSq = 0; + size_t clpPointIndex=0; + // iterate through points + for (Path::size_type j = 0; j < size; j++) { - IntPoint pt = inp.at(i); - IntPoint clp; // to hold closest point - double ptPar; - double distSqrd = DistancePointToLineSegSquared(p1, p2, pt, clp, ptPar, false); - if (distSqrd < tolSqrd) // collinear - extend same segment to end with pt + distSq = DistanceSqrd(tmp.at(j), inp.front()); + if (distSq < minDistSq) { - outp.pop_back(); - outp.push_back(pt); - if (DistanceSqrd(p1, p2) < tolSqrd) - p2 = pt; - } - else // new segment - start with new p1,p2 - { - p1 = outp.back(); - p2 = pt; - outp.push_back(pt); + clpPointIndex = j; + minDistSq=distSq; } } + + outpt.clear(); + for (size_t i = 0; i < tmp.size(); i++) + { + long index = clpPointIndex + long(i); + if (index >= long(tmp.size())) + index -= long(tmp.size()); + outpt.push_back(tmp.at(index)); + } + } double DistancePointToPathsSqrd(const Paths &paths, const IntPoint &pt, IntPoint &closestPointOnPath, @@ -1654,10 +1655,10 @@ std::list Adaptive2d::Execute(const DPaths &stockPaths, const DP scaleFactor = RESOLUTION_FACTOR / tolerance; if (stepOverFactor * toolDiameter < 1.0) scaleFactor *= 1.0 / (stepOverFactor * toolDiameter); - if (scaleFactor > 250) - scaleFactor = 250; + if (scaleFactor > 1000) + scaleFactor = 1000; - scaleFactor = round(scaleFactor); + //scaleFactor = round(scaleFactor); current_region=0; cout << "Tool Diameter: " << toolDiameter << endl; @@ -1716,12 +1717,14 @@ std::list Adaptive2d::Execute(const DPaths &stockPaths, const DP std::pair pt = paths[i][j]; cpth.push_back(IntPoint(long(pt.first * scaleFactor), long(pt.second * scaleFactor))); } - converted.push_back(cpth); + Path cpth2; + CleanPath(cpth,cpth2,FINISHING_CLEAN_PATH_TOLERANCE); + converted.push_back(cpth2); } DeduplicatePaths(converted, inputPaths); ConnectPaths(inputPaths, inputPaths); - SimplifyPolygons(inputPaths); + SimplifyPolygons(inputPaths); ApplyStockToLeave(inputPaths); //************************* @@ -1736,10 +1739,12 @@ std::list Adaptive2d::Execute(const DPaths &stockPaths, const DP std::pair pt = stockPaths[i][j]; cpth.push_back(IntPoint(long(pt.first * scaleFactor), long(pt.second * scaleFactor))); } + stockInputPaths.push_back(cpth); } SimplifyPolygons(stockInputPaths); + //CleanPolygons(stockInputPaths,0.707); //*************************************** // Resolve hierarchy and run processing @@ -3056,6 +3061,8 @@ void Adaptive2d::ProcessPolyNode(Paths boundPaths, Paths toolBoundPaths) } } + // make sure it's closed + finCleaned.push_back(finCleaned.front()); AppendToolPath(progressPaths, output, finCleaned, cleared, cleared, toolBoundPaths); cleared.ExpandCleared(finCleaned); diff --git a/src/Mod/Path/libarea/Adaptive.hpp b/src/Mod/Path/libarea/Adaptive.hpp index 060e8a858b..9cd674075b 100644 --- a/src/Mod/Path/libarea/Adaptive.hpp +++ b/src/Mod/Path/libarea/Adaptive.hpp @@ -109,7 +109,7 @@ class Adaptive2d Paths inputPaths; Paths stockInputPaths; int polyTreeNestingLimit = 0; - double scaleFactor = 100; + long scaleFactor = 100; double stepOverScaled = 1; long toolRadiusScaled = 10; long finishPassOffsetScaled = 0; @@ -146,7 +146,7 @@ class Adaptive2d void ApplyStockToLeave(Paths &inputPaths); private: // constants for fine tuning - const double RESOLUTION_FACTOR = 8.0; + const double RESOLUTION_FACTOR = 16.0; const int MAX_ITERATIONS = 10; const double AREA_ERROR_FACTOR = 0.05; /* how precise to match the cut area to optimal, reasonable value: 0.05 = 5%*/ const size_t ANGLE_HISTORY_POINTS = 3; // used for angle prediction @@ -157,9 +157,8 @@ class Adaptive2d const double ENGAGE_AREA_THR_FACTOR = 0.5; // influences minimal engage area const double ENGAGE_SCAN_DISTANCE_FACTOR = 0.2; // influences the engage scan/stepping distance - const double CLEAN_PATH_TOLERANCE = 2; - const double FINISHING_CLEAN_PATH_TOLERANCE = 1; - + const double CLEAN_PATH_TOLERANCE = 1.41; // should be >1 + const double FINISHING_CLEAN_PATH_TOLERANCE = 1.41; // should be >1 const long PASSES_LIMIT = __LONG_MAX__; // limit used while debugging const long POINTS_PER_PASS_LIMIT = __LONG_MAX__; // limit used while debugging