Path: Adaptive - performance optimization for larger models
- utilizing bounding boxes - changed the alg. for resolving tool down linking paths, resolution is no longer based on clipper offsets as offset alg. tends to become slow - new tool down linking alg. also should be better in finding shorter linking paths - lead-in lead-out improvements
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -19,14 +19,11 @@
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include "clipper.hpp"
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#ifndef ADAPTIVE_HPP
|
||||
#define ADAPTIVE_HPP
|
||||
|
||||
@@ -42,118 +39,138 @@
|
||||
#define M_PI 3.141592653589793238
|
||||
#endif
|
||||
|
||||
|
||||
//#define DEV_MODE
|
||||
|
||||
#define NTOL 1.0e-7 // numeric tolerance
|
||||
#define NTOL 1.0e-7 // numeric tolerance
|
||||
|
||||
namespace AdaptivePath {
|
||||
using namespace ClipperLib;
|
||||
namespace AdaptivePath
|
||||
{
|
||||
using namespace ClipperLib;
|
||||
|
||||
enum MotionType { mtCutting = 0, mtLinkClear = 1, mtLinkNotClear = 2, mtLinkClearAtPrevPass = 3 };
|
||||
enum MotionType
|
||||
{
|
||||
mtCutting = 0,
|
||||
mtLinkClear = 1,
|
||||
mtLinkNotClear = 2,
|
||||
mtLinkClearAtPrevPass = 3
|
||||
};
|
||||
|
||||
enum OperationType { otClearingInside = 0, otClearingOutside = 1, otProfilingInside = 2, otProfilingOutside = 3 };
|
||||
enum OperationType
|
||||
{
|
||||
otClearingInside = 0,
|
||||
otClearingOutside = 1,
|
||||
otProfilingInside = 2,
|
||||
otProfilingOutside = 3
|
||||
};
|
||||
|
||||
typedef std::pair<double,double> DPoint;
|
||||
typedef std::vector<DPoint> DPath;
|
||||
typedef std::vector<DPath> DPaths;
|
||||
typedef std::pair<int,DPath> TPath; // first parameter is MotionType, must use int due to problem with serialization to JSON in python
|
||||
typedef std::pair<double, double> DPoint;
|
||||
typedef std::vector<DPoint> DPath;
|
||||
typedef std::vector<DPath> DPaths;
|
||||
typedef std::pair<int, DPath> TPath; // first parameter is MotionType, must use int due to problem with serialization to JSON in python
|
||||
|
||||
// struct TPath { #this does not work correctly with pybind, changed to pair
|
||||
// DPath Points;
|
||||
// MotionType MType;
|
||||
// };
|
||||
class ClearedArea;
|
||||
|
||||
typedef std::vector<TPath> TPaths;
|
||||
// struct TPath { #this does not work correctly with pybind, changed to pair
|
||||
// DPath Points;
|
||||
// MotionType MType;
|
||||
// };
|
||||
|
||||
struct AdaptiveOutput {
|
||||
DPoint HelixCenterPoint;
|
||||
DPoint StartPoint;
|
||||
TPaths AdaptivePaths;
|
||||
int ReturnMotionType; // MotionType enum, problem with serialization if enum is used
|
||||
};
|
||||
typedef std::vector<TPath> TPaths;
|
||||
|
||||
// used to isolate state -> enable potential adding of multi-threaded processing of separate regions
|
||||
struct AdaptiveOutput
|
||||
{
|
||||
DPoint HelixCenterPoint;
|
||||
DPoint StartPoint;
|
||||
TPaths AdaptivePaths;
|
||||
int ReturnMotionType; // MotionType enum, problem with serialization if enum is used
|
||||
};
|
||||
|
||||
class Adaptive2d {
|
||||
public:
|
||||
Adaptive2d();
|
||||
double toolDiameter=5;
|
||||
double helixRampDiameter=0;
|
||||
double stepOverFactor = 0.2;
|
||||
double tolerance=0.1;
|
||||
double stockToLeave=0;
|
||||
bool forceInsideOut = true;
|
||||
double keepToolDownDistRatio = 3.0; // keep tool down distance ratio
|
||||
OperationType opType = OperationType::otClearingInside;
|
||||
// used to isolate state -> enable potential adding of multi-threaded processing of separate regions
|
||||
|
||||
std::list<AdaptiveOutput> Execute(const DPaths &stockPaths, const DPaths &paths, std::function<bool(TPaths)> progressCallbackFn);
|
||||
class Adaptive2d
|
||||
{
|
||||
public:
|
||||
Adaptive2d();
|
||||
double toolDiameter = 5;
|
||||
double helixRampDiameter = 0;
|
||||
double stepOverFactor = 0.2;
|
||||
double tolerance = 0.1;
|
||||
double stockToLeave = 0;
|
||||
bool forceInsideOut = true;
|
||||
double keepToolDownDistRatio = 3.0; // keep tool down distance ratio
|
||||
OperationType opType = OperationType::otClearingInside;
|
||||
|
||||
#ifdef DEV_MODE
|
||||
/*for debugging*/
|
||||
std::function<void(double cx,double cy, double radius, int color)> DrawCircleFn;
|
||||
std::function<void(const DPath &, int color)> DrawPathFn;
|
||||
std::function<void()> ClearScreenFn;
|
||||
#endif
|
||||
std::list<AdaptiveOutput> Execute(const DPaths &stockPaths, const DPaths &paths, std::function<bool(TPaths)> progressCallbackFn);
|
||||
|
||||
private:
|
||||
std::list<AdaptiveOutput> results;
|
||||
Paths inputPaths;
|
||||
Paths stockInputPaths;
|
||||
int polyTreeNestingLimit=0;
|
||||
double scaleFactor=100;
|
||||
long toolRadiusScaled=10;
|
||||
long finishPassOffsetScaled=0;
|
||||
long helixRampRadiusScaled=0;
|
||||
long bbox_size=0;
|
||||
double referenceCutArea=0;
|
||||
double optimalCutAreaPD=0;
|
||||
//double minCutAreaPD=0;
|
||||
bool stopProcessing=false;
|
||||
long unclearLinkingMoveCount = 0;
|
||||
#ifdef DEV_MODE
|
||||
/*for debugging*/
|
||||
std::function<void(double cx, double cy, double radius, int color)> DrawCircleFn;
|
||||
std::function<void(const DPath &, int color)> DrawPathFn;
|
||||
std::function<void()> ClearScreenFn;
|
||||
#endif
|
||||
|
||||
time_t lastProgressTime = 0;
|
||||
|
||||
std::function<bool(TPaths)> * progressCallback=NULL;
|
||||
Path toolGeometry; // tool geometry at coord 0,0, should not be modified
|
||||
private:
|
||||
std::list<AdaptiveOutput> results;
|
||||
Paths inputPaths;
|
||||
Paths stockInputPaths;
|
||||
int polyTreeNestingLimit = 0;
|
||||
double scaleFactor = 100;
|
||||
long toolRadiusScaled = 10;
|
||||
long finishPassOffsetScaled = 0;
|
||||
long helixRampRadiusScaled = 0;
|
||||
long bbox_size = 0;
|
||||
double referenceCutArea = 0;
|
||||
double optimalCutAreaPD = 0;
|
||||
//double minCutAreaPD=0;
|
||||
bool stopProcessing = false;
|
||||
long unclearLinkingMoveCount = 0;
|
||||
|
||||
void ProcessPolyNode(Paths boundPaths, Paths toolBoundPaths);
|
||||
bool FindEntryPoint(TPaths &progressPaths,const Paths & toolBoundPaths,const Paths &bound, Paths &cleared /*output*/,
|
||||
IntPoint &entryPoint /*output*/, IntPoint & toolPos, DoublePoint & toolDir);
|
||||
bool FindEntryPointOutside(TPaths &progressPaths,const Paths & toolBoundPaths,const Paths &bound, Paths &cleared /*output*/,
|
||||
IntPoint &entryPoint /*output*/, IntPoint & toolPos, DoublePoint & toolDir);
|
||||
double CalcCutArea(Clipper & clip,const IntPoint &toolPos, const IntPoint &newToolPos, const Paths &cleared_paths, bool preventConvetionalMode=true);
|
||||
void AppendToolPath(TPaths &progressPaths,AdaptiveOutput & output,const Path & passToolPath,const Paths & cleared,const Paths & toolBoundPaths);
|
||||
bool IsClearPath(const Path & path,const Paths & cleared, double safetyDistanceScaled=0);
|
||||
bool IsAllowedToCutTrough(const IntPoint &p1,const IntPoint &p2,const Paths & cleared,const Paths & toolBoundPaths, double areaFactor=1.5, bool skipBoundsCheck=false);
|
||||
time_t lastProgressTime = 0;
|
||||
|
||||
friend class EngagePoint; // for CalcCutArea
|
||||
std::function<bool(TPaths)> *progressCallback = NULL;
|
||||
Path toolGeometry; // tool geometry at coord 0,0, should not be modified
|
||||
|
||||
void CheckReportProgress(TPaths &progressPaths,bool force=false);
|
||||
void AddPathsToProgress(TPaths &progressPaths,const Paths paths, MotionType mt=MotionType::mtCutting);
|
||||
void AddPathToProgress(TPaths &progressPaths,const Path pth, MotionType mt=MotionType::mtCutting);
|
||||
void ApplyStockToLeave(Paths &inputPaths);
|
||||
private: // constants for fine tuning
|
||||
const double RESOLUTION_FACTOR = 8.0;
|
||||
const int MAX_ITERATIONS = 16;
|
||||
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
|
||||
const int DIRECTION_SMOOTHING_BUFLEN=3; // gyro points - used for angle smoothing
|
||||
void ProcessPolyNode(Paths boundPaths, Paths toolBoundPaths);
|
||||
bool FindEntryPoint(TPaths &progressPaths, const Paths &toolBoundPaths, const Paths &bound, ClearedArea &cleared /*output*/,
|
||||
IntPoint &entryPoint /*output*/, IntPoint &toolPos, DoublePoint &toolDir);
|
||||
bool FindEntryPointOutside(TPaths &progressPaths, const Paths &toolBoundPaths, const Paths &bound, ClearedArea &cleared /*output*/,
|
||||
IntPoint &entryPoint /*output*/, IntPoint &toolPos, DoublePoint &toolDir);
|
||||
double CalcCutArea(Clipper &clip, const IntPoint &toolPos, const IntPoint &newToolPos, ClearedArea &clearedArea, bool preventConvetionalMode = true);
|
||||
void AppendToolPath(TPaths &progressPaths, AdaptiveOutput &output, const Path &passToolPath, ClearedArea &clearedAreaBefore,
|
||||
ClearedArea &clearedAreaAfter, const Paths &toolBoundPaths);
|
||||
bool IsClearPath(const Path &path, ClearedArea &clearedArea, double safetyDistanceScaled = 0);
|
||||
bool IsAllowedToCutTrough(const IntPoint &p1, const IntPoint &p2, ClearedArea &clearedArea, const Paths &toolBoundPaths, double areaFactor = 1.5, bool skipBoundsCheck = false);
|
||||
bool MakeLeadPath(bool leadIn, const IntPoint &startPoint, const DoublePoint &startDir, const IntPoint &beaconPoint,
|
||||
ClearedArea &clearedArea, const Paths &toolBoundPaths, Path &output);
|
||||
|
||||
const double ENGAGE_AREA_THR_FACTOR=0.2; // influences minimal engage area (factor relation to optimal)
|
||||
const double ENGAGE_SCAN_DISTANCE_FACTOR=0.1; // influences the engage scan/stepping distance
|
||||
bool ResolveLinkPath(const IntPoint &startPoint, const IntPoint &endPoint, ClearedArea &clearedArea, Path &output);
|
||||
|
||||
const double CLEAN_PATH_TOLERANCE = 0.5;
|
||||
const double FINISHING_CLEAN_PATH_TOLERANCE = 0.1;
|
||||
friend class EngagePoint; // for CalcCutArea
|
||||
|
||||
// used for filtering out of insignificant cuts:
|
||||
const double MIN_CUT_AREA_FACTOR = 0.1; // influences filtering of cuts that with cumulative area below threshold, reasonable value is between 0.1 and 1
|
||||
void CheckReportProgress(TPaths &progressPaths, bool force = false);
|
||||
void AddPathsToProgress(TPaths &progressPaths, const Paths paths, MotionType mt = MotionType::mtCutting);
|
||||
void AddPathToProgress(TPaths &progressPaths, const Path pth, MotionType mt = MotionType::mtCutting);
|
||||
void ApplyStockToLeave(Paths &inputPaths);
|
||||
|
||||
const long PASSES_LIMIT = __LONG_MAX__; // limit used while debugging
|
||||
const long POINTS_PER_PASS_LIMIT = __LONG_MAX__; // limit used while debugging
|
||||
const time_t PROGRESS_TICKS = CLOCKS_PER_SEC/20; // progress report interval
|
||||
private: // constants for fine tuning
|
||||
const double RESOLUTION_FACTOR = 8.0;
|
||||
const int MAX_ITERATIONS = 16;
|
||||
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
|
||||
const int DIRECTION_SMOOTHING_BUFLEN = 3; // gyro points - used for angle smoothing
|
||||
|
||||
const double ENGAGE_AREA_THR_FACTOR = 0.2; // influences minimal engage area (factor relation to optimal)
|
||||
const double ENGAGE_SCAN_DISTANCE_FACTOR = 0.5; // influences the engage scan/stepping distance
|
||||
|
||||
};
|
||||
}
|
||||
const double CLEAN_PATH_TOLERANCE = 0.5;
|
||||
const double FINISHING_CLEAN_PATH_TOLERANCE = 0.1;
|
||||
|
||||
// used for filtering out of insignificant cuts:
|
||||
const double MIN_CUT_AREA_FACTOR = 0.1; // influences filtering of cuts that with cumulative area below threshold, reasonable value is between 0.1 and 1
|
||||
|
||||
const long PASSES_LIMIT = __LONG_MAX__; // limit used while debugging
|
||||
const long POINTS_PER_PASS_LIMIT = __LONG_MAX__; // limit used while debugging
|
||||
const time_t PROGRESS_TICKS = CLOCKS_PER_SEC / 10; // progress report interval
|
||||
};
|
||||
} // namespace AdaptivePath
|
||||
#endif
|
||||
Reference in New Issue
Block a user