Files
create/src/Mod/Path/libarea/Adaptive.hpp

129 lines
4.7 KiB
C++

#include "clipper.hpp"
#include <vector>
#include <list>
#include <time.h>
#ifndef ADAPTIVE_HPP
#define ADAPTIVE_HPP
#ifndef __DBL_MAX__
#define __DBL_MAX__ 1.7976931348623158e+308
#endif
#ifndef __LONG_MAX__
#define __LONG_MAX__ 2147483647
#endif
#ifndef M_PI
#define M_PI 3.141592653589793238
#endif
//#define DEV_MODE
#define NTOL 1.0e-7 // numeric tolerance
namespace AdaptivePath {
using namespace ClipperLib;
enum MotionType { mtCutting = 0, mtLinkClear = 1, mtLinkNotClear = 2, mtLinkClearAtPrevPass = 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
// struct TPath { #this does not work correctly with pybind, changed to pair
// DPath Points;
// MotionType MType;
// };
typedef std::vector<TPath> TPaths;
struct AdaptiveOutput {
DPoint HelixCenterPoint;
DPoint StartPoint;
TPaths AdaptivePaths;
int ReturnMotionType; // MotionType enum, problem with serialization if enum is used
};
// used to isolate state -> enable potential adding of multi-threaded processing of separate regions
class Adaptive2d {
public:
Adaptive2d();
double toolDiameter=5;
double helixRampDiameter=0;
double stepOverFactor = 0.2;
double tolerance=0.1;
double stockToLeave=0;
bool forceInsideOut = true;
OperationType opType = OperationType::otClearingInside;
std::list<AdaptiveOutput> Execute(const DPaths &stockPaths, const DPaths &paths, std::function<bool(TPaths)> progressCallbackFn);
#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
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;
time_t lastProgressTime = 0;
std::function<bool(TPaths)> * progressCallback=NULL;
Path toolGeometry; // tool geometry at coord 0,0, should not be modified
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);
void AppendToolPath(AdaptiveOutput & output,const Path & passToolPath,const Paths & cleared,const Paths & toolBoundPaths, bool close=false);
bool CheckCollision(const IntPoint &lastPoint,const IntPoint &nextPoint,const Paths & cleared);
friend class EngagePoint; // for CalcCutArea
void CheckReportProgress(TPaths &progressPaths,bool force=false);
void AddPathsToProgress(TPaths &progressPaths,Paths paths);
private: // constants for fine tuning
const bool preventConvetionalMode = true;
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.1; // 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/20; // progress report interval
};
}
#endif