libarea: added OffsetWithClipper function
Also added a few extra setting variables. OffsetWithClipper perform offset operation using ClipperLib::ClipperOffset.
This commit is contained in:
parent
2a67c7f0ae
commit
9cf075a806
|
@ -10,7 +10,11 @@
|
|||
|
||||
double CArea::m_accuracy = 0.01;
|
||||
double CArea::m_units = 1.0;
|
||||
bool CArea::m_clipper_simple = false;
|
||||
double CArea::m_clipper_clean_distance = 0.0;
|
||||
bool CArea::m_fit_arcs = true;
|
||||
int CArea::m_min_arc_points = 4;
|
||||
int CArea::m_max_arc_points = 100;
|
||||
double CArea::m_single_area_processing_length = 0.0;
|
||||
double CArea::m_processing_done = 0.0;
|
||||
bool CArea::m_please_abort = false;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#define AREA_HEADER
|
||||
|
||||
#include "Curve.h"
|
||||
#include "clipper.hpp"
|
||||
|
||||
enum PocketMode
|
||||
{
|
||||
|
@ -42,7 +43,11 @@ public:
|
|||
std::list<CCurve> m_curves;
|
||||
static double m_accuracy;
|
||||
static double m_units; // 1.0 for mm, 25.4 for inches. All points are multiplied by this before going to the engine
|
||||
static bool m_clipper_simple;
|
||||
static double m_clipper_clean_distance;
|
||||
static bool m_fit_arcs;
|
||||
static int m_min_arc_points;
|
||||
static int m_max_arc_points;
|
||||
static double m_processing_done; // 0.0 to 100.0, set inside MakeOnePocketCurve
|
||||
static double m_single_area_processing_length;
|
||||
static double m_after_MakeOffsets_length;
|
||||
|
@ -50,6 +55,7 @@ public:
|
|||
static double m_split_processing_length;
|
||||
static bool m_set_processing_length_in_split;
|
||||
static bool m_please_abort; // the user sets this from another thread, to tell MakeOnePocketCurve to finish with no result.
|
||||
static double m_clipper_scale;
|
||||
|
||||
void append(const CCurve& curve);
|
||||
void Subtract(const CArea& a2);
|
||||
|
@ -58,6 +64,11 @@ public:
|
|||
static CArea UniteCurves(std::list<CCurve> &curves);
|
||||
void Xor(const CArea& a2);
|
||||
void Offset(double inwards_value);
|
||||
void OffsetWithClipper(double offset,
|
||||
ClipperLib::JoinType joinType=ClipperLib::jtRound,
|
||||
ClipperLib::EndType endType=ClipperLib::etOpenRound,
|
||||
double miterLimit = 5.0,
|
||||
double roundPrecision = 0.0);
|
||||
void Thicken(double value);
|
||||
void FitArcs();
|
||||
unsigned int num_curves(){return static_cast<int>(m_curves.size());}
|
||||
|
|
|
@ -12,7 +12,7 @@ using namespace ClipperLib;
|
|||
bool CArea::HolesLinked(){ return false; }
|
||||
|
||||
//static const double PI = 3.1415926535897932;
|
||||
static double Clipper4Factor = 10000.0;
|
||||
double CArea::m_clipper_scale = 10000.0;
|
||||
|
||||
class DoubleAreaPoint
|
||||
{
|
||||
|
@ -20,8 +20,8 @@ public:
|
|||
double X, Y;
|
||||
|
||||
DoubleAreaPoint(double x, double y){X = x; Y = y;}
|
||||
DoubleAreaPoint(const IntPoint& p){X = (double)(p.X) / Clipper4Factor; Y = (double)(p.Y) / Clipper4Factor;}
|
||||
IntPoint int_point(){return IntPoint((long64)(X * Clipper4Factor), (long64)(Y * Clipper4Factor));}
|
||||
DoubleAreaPoint(const IntPoint& p){X = (double)(p.X) / CArea::m_clipper_scale; Y = (double)(p.Y) / CArea::m_clipper_scale;}
|
||||
IntPoint int_point(){return IntPoint((long64)(X * CArea::m_clipper_scale), (long64)(Y * CArea::m_clipper_scale));}
|
||||
};
|
||||
|
||||
static std::list<DoubleAreaPoint> pts_for_AddVertex;
|
||||
|
@ -81,10 +81,10 @@ static void AddVertex(const CVertex& vertex, const CVertex* prev_vertex)
|
|||
else
|
||||
Segments=(int)ceil(-phit/dphi);
|
||||
|
||||
if (Segments < 1)
|
||||
Segments=1;
|
||||
if (Segments > 100)
|
||||
Segments=100;
|
||||
if (Segments < CArea::m_min_arc_points)
|
||||
Segments = CArea::m_min_arc_points;
|
||||
if (Segments > CArea::m_max_arc_points)
|
||||
Segments=CArea::m_max_arc_points;
|
||||
|
||||
dphi=phit/(Segments);
|
||||
|
||||
|
@ -139,6 +139,7 @@ static void MakeLoop(const DoubleAreaPoint &pt0, const DoubleAreaPoint &pt1, con
|
|||
static void OffsetWithLoops(const TPolyPolygon &pp, TPolyPolygon &pp_new, double inwards_value)
|
||||
{
|
||||
Clipper c;
|
||||
c.StrictlySimple(CArea::m_clipper_simple);
|
||||
|
||||
bool inwards = (inwards_value > 0);
|
||||
bool reverse = false;
|
||||
|
@ -251,6 +252,7 @@ static void MakeObround(const Point &pt0, const CVertex &vt1, double radius)
|
|||
static void OffsetSpansWithObrounds(const CArea& area, TPolyPolygon &pp_new, double radius)
|
||||
{
|
||||
Clipper c;
|
||||
c.StrictlySimple(CArea::m_clipper_simple);
|
||||
|
||||
|
||||
for(std::list<CCurve>::const_iterator It = area.m_curves.begin(); It != area.m_curves.end(); It++)
|
||||
|
@ -355,8 +357,11 @@ static void MakePoly(const CCurve& curve, TPolygon &p)
|
|||
}
|
||||
}
|
||||
|
||||
static void SetFromResult( CCurve& curve, const TPolygon& p, bool reverse = true )
|
||||
static void SetFromResult( CCurve& curve, TPolygon& p, bool reverse = true )
|
||||
{
|
||||
if(CArea::m_clipper_clean_distance >= Point::tolerance)
|
||||
CleanPolygon(p,CArea::m_clipper_clean_distance);
|
||||
|
||||
for(unsigned int j = 0; j < p.size(); j++)
|
||||
{
|
||||
const IntPoint &pt = p[j];
|
||||
|
@ -372,14 +377,14 @@ static void SetFromResult( CCurve& curve, const TPolygon& p, bool reverse = true
|
|||
if(CArea::m_fit_arcs)curve.FitArcs();
|
||||
}
|
||||
|
||||
static void SetFromResult( CArea& area, const TPolyPolygon& pp, bool reverse = true )
|
||||
static void SetFromResult( CArea& area, TPolyPolygon& pp, bool reverse = true )
|
||||
{
|
||||
// delete existing geometry
|
||||
area.m_curves.clear();
|
||||
|
||||
for(unsigned int i = 0; i < pp.size(); i++)
|
||||
{
|
||||
const TPolygon& p = pp[i];
|
||||
TPolygon& p = pp[i];
|
||||
|
||||
area.m_curves.push_back(CCurve());
|
||||
CCurve &curve = area.m_curves.back();
|
||||
|
@ -390,6 +395,7 @@ static void SetFromResult( CArea& area, const TPolyPolygon& pp, bool reverse = t
|
|||
void CArea::Subtract(const CArea& a2)
|
||||
{
|
||||
Clipper c;
|
||||
c.StrictlySimple(CArea::m_clipper_simple);
|
||||
TPolyPolygon pp1, pp2;
|
||||
MakePolyPoly(*this, pp1);
|
||||
MakePolyPoly(a2, pp2);
|
||||
|
@ -403,6 +409,7 @@ void CArea::Subtract(const CArea& a2)
|
|||
void CArea::Intersect(const CArea& a2)
|
||||
{
|
||||
Clipper c;
|
||||
c.StrictlySimple(CArea::m_clipper_simple);
|
||||
TPolyPolygon pp1, pp2;
|
||||
MakePolyPoly(*this, pp1);
|
||||
MakePolyPoly(a2, pp2);
|
||||
|
@ -416,6 +423,7 @@ void CArea::Intersect(const CArea& a2)
|
|||
void CArea::Union(const CArea& a2)
|
||||
{
|
||||
Clipper c;
|
||||
c.StrictlySimple(CArea::m_clipper_simple);
|
||||
TPolyPolygon pp1, pp2;
|
||||
MakePolyPoly(*this, pp1);
|
||||
MakePolyPoly(a2, pp2);
|
||||
|
@ -430,6 +438,7 @@ void CArea::Union(const CArea& a2)
|
|||
CArea CArea::UniteCurves(std::list<CCurve> &curves)
|
||||
{
|
||||
Clipper c;
|
||||
c.StrictlySimple(CArea::m_clipper_simple);
|
||||
|
||||
TPolyPolygon pp;
|
||||
|
||||
|
@ -452,6 +461,7 @@ CArea CArea::UniteCurves(std::list<CCurve> &curves)
|
|||
void CArea::Xor(const CArea& a2)
|
||||
{
|
||||
Clipper c;
|
||||
c.StrictlySimple(CArea::m_clipper_simple);
|
||||
TPolyPolygon pp1, pp2;
|
||||
MakePolyPoly(*this, pp1);
|
||||
MakePolyPoly(a2, pp2);
|
||||
|
@ -471,6 +481,37 @@ void CArea::Offset(double inwards_value)
|
|||
this->Reorder();
|
||||
}
|
||||
|
||||
void CArea::OffsetWithClipper(double offset,
|
||||
JoinType joinType/* =jtRound */,
|
||||
EndType endType/* =etOpenRound */,
|
||||
double miterLimit/* = 5.0 */,
|
||||
double roundPrecision/* = 0.0 */)
|
||||
{
|
||||
offset *= m_units*m_clipper_scale;
|
||||
if(roundPrecision == 0.0) {
|
||||
// Clipper roundPrecision definition: https://goo.gl/4odfQh
|
||||
double dphi=acos(1.0-m_accuracy*m_clipper_scale/fabs(offset));
|
||||
int Segments=(int)ceil(PI/dphi);
|
||||
if (Segments < 2*CArea::m_min_arc_points)
|
||||
Segments = 2*CArea::m_min_arc_points;
|
||||
if (Segments > CArea::m_max_arc_points)
|
||||
Segments=CArea::m_max_arc_points;
|
||||
dphi = PI/Segments;
|
||||
roundPrecision = (1.0-cos(dphi))*fabs(offset);
|
||||
}else
|
||||
roundPrecision *= m_clipper_scale;
|
||||
|
||||
ClipperOffset clipper(miterLimit,roundPrecision);
|
||||
TPolyPolygon pp, pp2;
|
||||
MakePolyPoly(*this, pp, false);
|
||||
int i=0;
|
||||
for(const CCurve &c : m_curves)
|
||||
clipper.AddPath(pp[i++],joinType,c.IsClosed()?etClosedPolygon:endType);
|
||||
clipper.Execute(pp2,(long64)(offset));
|
||||
SetFromResult(*this, pp2, false);
|
||||
this->Reorder();
|
||||
}
|
||||
|
||||
void CArea::Thicken(double value)
|
||||
{
|
||||
TPolyPolygon pp;
|
||||
|
|
Loading…
Reference in New Issue
Block a user