Path: Adaptive - feature to clear from outside stock bounday inwards

This commit is contained in:
kreso-t
2018-09-01 17:45:31 +02:00
committed by wmayer
parent 364daff4c7
commit 365227a049
6 changed files with 249 additions and 109 deletions

View File

@@ -793,7 +793,7 @@ namespace AdaptivePath {
/****************************************
// Adaptive2d - Execute
*****************************************/
std::list<AdaptiveOutput> Adaptive2d::Execute(const DPaths &paths, std::function<bool(TPaths)> progressCallbackFn) {
std::list<AdaptiveOutput> Adaptive2d::Execute(const DPaths &stockPaths, const DPaths &paths, std::function<bool(TPaths)> progressCallbackFn) {
//**********************************
// Initializations
// **********************************
@@ -845,6 +845,7 @@ namespace AdaptivePath {
// **********************
// Convert input paths to clipper
//************************
inputPaths.clear();
for(size_t i=0;i<paths.size();i++) {
Path cpth;
for(size_t j=0;j<paths[i].size();j++) {
@@ -855,6 +856,21 @@ namespace AdaptivePath {
}
SimplifyPolygons(inputPaths);
//************************
// convert stock paths
// *************************
stockInputPaths.clear();
for(size_t i=0;i<stockPaths.size();i++) {
Path cpth;
for(size_t j=0;j<stockPaths[i].size();j++) {
std::pair<double,double> pt = stockPaths[i][j];
cpth.push_back(IntPoint(long(pt.first*scaleFactor),long(pt.second*scaleFactor)));
}
stockInputPaths.push_back(cpth);
}
SimplifyPolygons(stockInputPaths);
if(stockToLeave>NTOL) {
clipof.Clear();
clipof.AddPaths(inputPaths,JoinType::jtRound,EndType::etClosedPolygon);
@@ -874,7 +890,18 @@ namespace AdaptivePath {
// Resolve hierarchy and run processing
// ********************************
if(opType==OperationType::otClearing) {
if(opType==OperationType::otClearingInside || opType==OperationType::otClearingOutside) {
// add stock paths, with overshooting
if(opType==OperationType::otClearingOutside) {
clipof.Clear();
clipof.AddPaths(stockInputPaths,JoinType::jtRound,EndType::etClosedPolygon);
double overshootDistance =2*toolRadiusScaled + toolRadiusScaled*stepOverFactor;
if(forceInsideOut) overshootDistance=0;
Paths stockOvershoot;
clipof.Execute(stockOvershoot,overshootDistance);
ReversePaths(stockOvershoot);
for(auto p : stockOvershoot) inputPaths.push_back(p);
}
clipof.Clear();
clipof.AddPaths(inputPaths,JoinType::jtRound,EndType::etClosedPolygon);
Paths paths;
@@ -942,7 +969,10 @@ namespace AdaptivePath {
return results;
}
bool Adaptive2d::FindEntryPoint(const Paths & toolBoundPaths,const Paths &boundPaths, Paths &cleared /*output-initial cleard area by helix*/, IntPoint &entryPoint /*output*/) {
bool Adaptive2d::FindEntryPoint(TPaths &progressPaths, const Paths & toolBoundPaths,const Paths &boundPaths,
Paths &cleared /*output-initial cleard area by helix*/,
IntPoint &entryPoint /*output*/,
IntPoint & toolPos, DoublePoint & toolDir) {
Paths incOffset;
Paths lastValidOffset;
Clipper clip;
@@ -1018,8 +1048,66 @@ namespace AdaptivePath {
}
//DrawCircle(entryPoint,scaleFactor,10);
if(!found) cerr<<"Start point not found!"<<endl;
if(found) {
// visualize/progress for helix
clipof.Clear();
Path hp;
hp << entryPoint;
clipof.AddPath(hp,JoinType::jtRound,EndType::etOpenRound);
Paths hps;
clipof.Execute(hps,helixRampRadiusScaled);
AddPathsToProgress(progressPaths,hps);
toolPos = IntPoint(entryPoint.X,entryPoint.Y - helixRampRadiusScaled);
toolDir = DoublePoint(1.0,0.0);
}
return found;
}
bool Adaptive2d::FindEntryPointOutside(TPaths &progressPaths, const Paths & toolBoundPaths,const Paths &boundPaths,
Paths &cleared /*output-initial cleard area by helix*/,
IntPoint &entryPoint /*output*/,
IntPoint & toolPos, DoublePoint & toolDir) {
Clipper clip;
ClipperOffset clipof;
// check if boundary shape to cut is outside the stock
// clip.AddPaths(boundPaths,PolyType::ptSubject, true);
// clip.AddPaths(stockInputPaths,PolyType::ptClip, true);
// Paths outsidePaths;
// clip.Execute(ClipType::ctDifference,outsidePaths);
for(const auto & pth : toolBoundPaths) {
for(size_t i=0;i<pth.size();i++) {
IntPoint checkPoint = pth[i];
IntPoint lastPoint = i>0 ? pth[i-1] : pth.back();
// if point is outside the stock
if(PointInPolygon(checkPoint,stockInputPaths.front())==0) {
clipof.Clear();
clipof.AddPaths(toolBoundPaths,JoinType::jtRound,EndType::etClosedPolygon);
Paths sol2;
clipof.Execute(sol2,toolRadiusScaled*stepOverFactor);
clipof.Clear();
clipof.AddPaths(sol2,JoinType::jtRound,EndType::etClosedLine);
clipof.Execute(cleared,toolRadiusScaled);
// trim cleared paths to stock boundary (only outside part remain)
clip.Clear();
clip.AddPaths(cleared,PolyType::ptSubject, true);
clip.AddPaths(stockInputPaths,PolyType::ptClip, true);
clip.Execute(ClipType::ctDifference,cleared);
AddPathsToProgress(progressPaths,cleared);
entryPoint=checkPoint;
toolPos = entryPoint;
// find tool dir
double len=sqrt(DistanceSqrd(lastPoint,checkPoint));
toolDir = DoublePoint((checkPoint.X - lastPoint.X)/len,(checkPoint.Y - lastPoint.Y)/len);
return true;
}
}
}
//AddPathsToProgress(progressPaths,outsidePaths);
return false;
}
/**
* returns true if line from lastPoint to nextPoint is clear from obstacles
@@ -1130,6 +1218,18 @@ namespace AdaptivePath {
while(progressPaths.front().second.size()>0) progressPaths.front().second.pop_back();
progressPaths.front().second.push_back(next);
}
void Adaptive2d::AddPathsToProgress(TPaths &progressPaths,Paths paths) {
for(const auto & pth :paths) {
if(pth.size()>0) {
progressPaths.push_back(TPath());
for(const auto pt: pth)
progressPaths.back().second.push_back(DPoint(double(pt.X)/scaleFactor,double(pt.Y)/scaleFactor));
progressPaths.back().second.push_back(DPoint(double(pth.front().X)/scaleFactor,double(pth.front().Y)/scaleFactor));
}
}
}
void Adaptive2d::ProcessPolyNode(Paths & boundPaths, Paths & toolBoundPaths) {
//cout << " Adaptive2d::ProcessPolyNode" << endl;
Perf_ProcessPolyNode.Start();
@@ -1142,10 +1242,21 @@ namespace AdaptivePath {
//SimplifyPolygons(toolBoundPaths);
CleanPolygons(toolBoundPaths);
//SimplifyPolygons(boundPaths);
CleanPolygons(toolBoundPaths);
//CleanPolygons(toolBoundPaths);
//AddPathsToProgress(progressPaths,toolBoundPaths);
IntPoint toolPos;
DoublePoint toolDir;
Paths cleared;
if(!FindEntryPoint(toolBoundPaths, boundPaths, cleared, entryPoint)) return;
bool outsideEntry = false;
if(FindEntryPointOutside(progressPaths, toolBoundPaths, boundPaths, cleared, entryPoint, toolPos,toolDir)) {
toolPos = IntPoint(entryPoint.X,entryPoint.Y);
toolDir = DoublePoint(1.0,0.0);
outsideEntry=true;
} else {
if(!FindEntryPoint(progressPaths, toolBoundPaths, boundPaths, cleared, entryPoint, toolPos,toolDir)) return;
}
//cout << "Entry point:" << entryPoint << endl;
Clipper clip;
ClipperOffset clipof;
@@ -1156,42 +1267,14 @@ namespace AdaptivePath {
long stepScaled = long(RESOLUTION_FACTOR);
IntPoint engagePoint;
IntPoint toolPos;
DoublePoint toolDir;
IntPoint newToolPos;
DoublePoint newToolDir;
// visualize/progress for boundPath
for(const auto & pth :toolBoundPaths) {
if(pth.size()>0) {
progressPaths.push_back(TPath());
for(const auto pt: pth)
progressPaths.back().second.push_back(DPoint(double(pt.X)/scaleFactor,double(pt.Y)/scaleFactor));
progressPaths.back().second.push_back(DPoint(double(pth.front().X)/scaleFactor,double(pth.front().Y)/scaleFactor));
}
}
CheckReportProgress(progressPaths, true);
// visualize/progress for helix
clipof.Clear();
Path hp;
hp << entryPoint;
clipof.AddPath(hp,JoinType::jtRound,EndType::etOpenRound);
Paths hps;
clipof.Execute(hps,helixRampRadiusScaled);
progressPaths.push_back(TPath());
// show in progress cb
for(auto & pt:hps[0]) {
progressPaths.back().second.push_back(DPoint(double(pt.X)/scaleFactor,double(pt.Y)/scaleFactor));
}
CheckReportProgress(progressPaths);
// find the first tool position and direction
toolPos = IntPoint(entryPoint.X,entryPoint.Y - helixRampRadiusScaled);
toolDir = DoublePoint(1.0,0.0);
output.StartPoint =DPoint(double(toolPos.X)/scaleFactor,double(toolPos.Y)/scaleFactor);
IntPoint startPoint = toolPos;
output.StartPoint =DPoint(double(startPoint.X)/scaleFactor,double(startPoint.Y)/scaleFactor);
bool firstEngagePoint=true;
Path passToolPath; // to store pass toolpath
@@ -1211,6 +1294,8 @@ namespace AdaptivePath {
long over_cut_count =0;
unclearLinkingMoveCount=0;
//long engage_no_cut_count=0;
double prevDistFromStart =0;
bool prevDistTrend = false;
double perf_total_len=0;
#ifdef DEV_MODE
@@ -1247,7 +1332,7 @@ namespace AdaptivePath {
*******************************/
for(long point_index=0;point_index<POINTS_PER_PASS_LIMIT;point_index++) {
if(stopProcessing) break;
//cout<<"Pass:"<< pass << " Point:" << point_index;
//cout<<"Pass:"<< pass << " Point:" << point_index << endl;
total_points++;
AverageDirection(gyro, toolDir);
Perf_DistanceToBoundary.Start();
@@ -1363,11 +1448,12 @@ namespace AdaptivePath {
}
if(firstEngagePoint) { // initial spiral shape need clearing in smaller intervals
double distFromEntry = sqrt(DistanceSqrd(toolPos,entryPoint));
double circ = distFromEntry * M_PI;
//cout << (circ/(16*RESOLUTION_FACTOR)) << endl;
if(toClearPath.size()>circ/(16*RESOLUTION_FACTOR)) {
// update cleared paths when trend of distance from start point changes sign (starts to get closer, or start to get farther)
double distFromStart = sqrt(DistanceSqrd(toolPos,startPoint));
bool distanceTrend = distFromStart > prevDistFromStart ? true : false;
if(distFromStart!=prevDistTrend) {
Perf_ExpandCleared.Start();
// expand cleared
clipof.Clear();
@@ -1381,8 +1467,10 @@ namespace AdaptivePath {
CleanPolygons(cleared);
toClearPath.clear();
Perf_ExpandCleared.Stop();
}
}
prevDistTrend = distanceTrend;
prevDistFromStart = distFromStart;
if(area>0) { // cut is ok - record it
if(toClearPath.size()==0) toClearPath.push_back(toolPos);
@@ -1463,6 +1551,14 @@ namespace AdaptivePath {
IntPoint lastPoint;
for(auto & pth: finishingPaths) {
// trim finishing passes outside the stock boundary - make no sense to cut where is no material
Paths diff;
clip.Clear();
clip.AddPath(pth,PolyType::ptSubject,true);
clip.AddPaths(stockInputPaths,PolyType::ptClip,true);
clip.Execute(ClipType::ctDifference,diff);
if(diff.size()>0) continue;
progressPaths.push_back(TPath());
// show in progress cb
for(auto & pt:pth) {