Convincing ClipperLib to use Slic3r's own Point type internally.

This commit is contained in:
Vojtech Bubnik 2021-04-21 20:15:49 +02:00
parent a15c16d40d
commit 8d0950ce12
14 changed files with 74 additions and 83 deletions

View File

@ -268,8 +268,6 @@ set(LIBDIR_BIN ${CMAKE_CURRENT_BINARY_DIR}/src)
include_directories(${LIBDIR}) include_directories(${LIBDIR})
# For generated header files # For generated header files
include_directories(${LIBDIR_BIN}/platform) include_directories(${LIBDIR_BIN}/platform)
# For libslic3r.h
include_directories(${LIBDIR}/clipper)
if(WIN32) if(WIN32)
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS) add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)

View File

@ -2,8 +2,9 @@ project(clipper)
cmake_minimum_required(VERSION 2.6) cmake_minimum_required(VERSION 2.6)
add_library(clipper STATIC add_library(clipper STATIC
clipper.cpp # We are using ClipperLib compiled as part of the libslic3r project using Slic3r::Point as its base type.
clipper.hpp # clipper.cpp
# clipper.hpp
clipper_z.cpp clipper_z.cpp
clipper_z.hpp clipper_z.hpp
) )

View File

@ -61,11 +61,15 @@
#define CLIPPERLIB_PROFILE_BLOCK(name) #define CLIPPERLIB_PROFILE_BLOCK(name)
#endif #endif
#ifdef use_xyz #ifdef CLIPPERLIB_NAMESPACE_PREFIX
namespace CLIPPERLIB_NAMESPACE_PREFIX {
#endif // CLIPPERLIB_NAMESPACE_PREFIX
#ifdef CLIPPERLIB_USE_XYZ
namespace ClipperLib_Z { namespace ClipperLib_Z {
#else /* use_xyz */ #else /* CLIPPERLIB_USE_XYZ */
namespace ClipperLib { namespace ClipperLib {
#endif /* use_xyz */ #endif /* CLIPPERLIB_USE_XYZ */
static double const pi = 3.141592653589793238; static double const pi = 3.141592653589793238;
static double const two_pi = pi *2; static double const two_pi = pi *2;
@ -335,7 +339,7 @@ inline cInt TopX(TEdge &edge, const cInt currentY)
void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip) void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
{ {
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
ip.z() = 0; ip.z() = 0;
#endif #endif
@ -467,7 +471,7 @@ inline void ReverseHorizontal(TEdge &e)
//progression of the bounds - ie so their xbots will align with the //progression of the bounds - ie so their xbots will align with the
//adjoining lower edge. [Helpful in the ProcessHorizontal() method.] //adjoining lower edge. [Helpful in the ProcessHorizontal() method.]
std::swap(e.Top.x(), e.Bot.x()); std::swap(e.Top.x(), e.Bot.x());
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
std::swap(e.Top.z(), e.Bot.z()); std::swap(e.Top.z(), e.Bot.z());
#endif #endif
} }
@ -1073,7 +1077,7 @@ Clipper::Clipper(int initOptions) :
m_StrictSimple = ((initOptions & ioStrictlySimple) != 0); m_StrictSimple = ((initOptions & ioStrictlySimple) != 0);
m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0); m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0);
m_HasOpenPaths = false; m_HasOpenPaths = false;
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
m_ZFill = 0; m_ZFill = 0;
#endif #endif
} }
@ -1637,7 +1641,7 @@ void Clipper::DeleteFromSEL(TEdge *e)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
void Clipper::SetZ(IntPoint& pt, TEdge& e1, TEdge& e2) void Clipper::SetZ(IntPoint& pt, TEdge& e1, TEdge& e2)
{ {
if (pt.z() != 0 || !m_ZFill) return; if (pt.z() != 0 || !m_ZFill) return;
@ -1655,7 +1659,7 @@ void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt)
bool e1Contributing = ( e1->OutIdx >= 0 ); bool e1Contributing = ( e1->OutIdx >= 0 );
bool e2Contributing = ( e2->OutIdx >= 0 ); bool e2Contributing = ( e2->OutIdx >= 0 );
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
SetZ(Pt, *e1, *e2); SetZ(Pt, *e1, *e2);
#endif #endif
@ -2641,7 +2645,7 @@ void Clipper::ProcessEdgesAtTopOfScanbeam(const cInt topY)
(ePrev->Curr.x() == e->Curr.x()) && (ePrev->WindDelta != 0)) (ePrev->Curr.x() == e->Curr.x()) && (ePrev->WindDelta != 0))
{ {
IntPoint pt = e->Curr; IntPoint pt = e->Curr;
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
SetZ(pt, *ePrev, *e); SetZ(pt, *ePrev, *e);
#endif #endif
OutPt* op = AddOutPt(ePrev, pt); OutPt* op = AddOutPt(ePrev, pt);
@ -4204,3 +4208,7 @@ std::ostream& operator <<(std::ostream &s, const Paths &p)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
} //ClipperLib namespace } //ClipperLib namespace
#ifdef CLIPPERLIB_NAMESPACE_PREFIX
} // namespace CLIPPERLIB_NAMESPACE_PREFIX
#endif // CLIPPERLIB_NAMESPACE_PREFIX

View File

@ -41,8 +41,8 @@
#define CLIPPER_VERSION "6.2.6" #define CLIPPER_VERSION "6.2.6"
//use_xyz: adds a Z member to IntPoint. Adds a minor cost to perfomance. //CLIPPERLIB_USE_XYZ: adds a Z member to IntPoint. Adds a minor cost to perfomance.
//#define use_xyz //#define CLIPPERLIB_USE_XYZ
//use_lines: Enables line clipping. Adds a very minor cost to performance. //use_lines: Enables line clipping. Adds a very minor cost to performance.
#define use_lines #define use_lines
@ -59,11 +59,15 @@
#include <functional> #include <functional>
#include <queue> #include <queue>
#ifdef use_xyz #ifdef CLIPPERLIB_NAMESPACE_PREFIX
namespace ClipperLib_Z { namespace CLIPPERLIB_NAMESPACE_PREFIX {
#else /* use_xyz */ #endif // CLIPPERLIB_NAMESPACE_PREFIX
namespace ClipperLib {
#endif /* use_xyz */ #ifdef CLIPPERLIB_USE_XYZ
namespace ClipperLib_Z {
#else
namespace ClipperLib {
#endif
enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }; enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor };
enum PolyType { ptSubject, ptClip }; enum PolyType { ptSubject, ptClip };
@ -90,43 +94,20 @@ enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative };
static constexpr cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL; static constexpr cInt const hiRange = 0x3FFFFFFFFFFFFFFFLL;
#endif // CLIPPERLIB_INT32 #endif // CLIPPERLIB_INT32
#if 1 #ifdef CLIPPERLIB_INTPOINT_TYPE
using IntPoint = CLIPPERLIB_INTPOINT_TYPE;
#else // CLIPPERLIB_INTPOINT_TYPE
using IntPoint = Eigen::Matrix<cInt, using IntPoint = Eigen::Matrix<cInt,
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
3 3
#else // use_xyz #else // CLIPPERLIB_USE_XYZ
2 2
#endif // use_xyz #endif // CLIPPERLIB_USE_XYZ
, 1, Eigen::DontAlign>; , 1, Eigen::DontAlign>;
using DoublePoint = Eigen::Matrix<double, 2, 1, Eigen::DontAlign>; #endif // CLIPPERLIB_INTPOINT_TYPE
#else
struct IntPoint { using DoublePoint = Eigen::Matrix<double, 2, 1, Eigen::DontAlign>;
cInt X;
cInt Y;
#ifdef use_xyz
cInt Z;
IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {};
#else
IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {};
#endif
friend inline bool operator== (const IntPoint& a, const IntPoint& b)
{
return a.X == b.X && a.Y == b.Y;
}
friend inline bool operator!= (const IntPoint& a, const IntPoint& b)
{
return a.X != b.X || a.Y != b.Y;
}
};
struct DoublePoint
{
double X;
double Y;
DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
DoublePoint(IntPoint ip) : X((double)ip.x()), Y((double)ip.y()) {}
};
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
typedef std::vector<IntPoint> Path; typedef std::vector<IntPoint> Path;
@ -141,7 +122,7 @@ std::ostream& operator <<(std::ostream &s, const Paths &p);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
typedef std::function<void(const IntPoint& e1bot, const IntPoint& e1top, const IntPoint& e2bot, const IntPoint& e2top, IntPoint& pt)> ZFillCallback; typedef std::function<void(const IntPoint& e1bot, const IntPoint& e1top, const IntPoint& e2bot, const IntPoint& e2top, IntPoint& pt)> ZFillCallback;
#endif #endif
@ -282,11 +263,11 @@ enum EdgeSide { esLeft = 1, esRight = 2};
}; };
// Point of an output polygon. // Point of an output polygon.
// 36B on 64bit system without use_xyz. // 36B on 64bit system without CLIPPERLIB_USE_XYZ.
struct OutPt { struct OutPt {
// 4B // 4B
int Idx; int Idx;
// 16B without use_xyz / 24B with use_xyz // 16B without CLIPPERLIB_USE_XYZ / 24B with CLIPPERLIB_USE_XYZ
IntPoint Pt; IntPoint Pt;
// 4B on 32bit system, 8B on 64bit system // 4B on 32bit system, 8B on 64bit system
OutPt *Next; OutPt *Next;
@ -381,7 +362,7 @@ public:
bool StrictlySimple() const {return m_StrictSimple;}; bool StrictlySimple() const {return m_StrictSimple;};
void StrictlySimple(bool value) {m_StrictSimple = value;}; void StrictlySimple(bool value) {m_StrictSimple = value;};
//set the callback function for z value filling on intersections (otherwise Z is 0) //set the callback function for z value filling on intersections (otherwise Z is 0)
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
void ZFillFunction(ZFillCallback zFillFunc) { m_ZFill = zFillFunc; } void ZFillFunction(ZFillCallback zFillFunc) { m_ZFill = zFillFunc; }
#endif #endif
protected: protected:
@ -414,7 +395,7 @@ private:
// Does the result go to a PolyTree or Paths? // Does the result go to a PolyTree or Paths?
bool m_UsingPolyTree; bool m_UsingPolyTree;
bool m_StrictSimple; bool m_StrictSimple;
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
ZFillCallback m_ZFill; //custom callback ZFillCallback m_ZFill; //custom callback
#endif #endif
void SetWindingCount(TEdge& edge) const; void SetWindingCount(TEdge& edge) const;
@ -467,7 +448,7 @@ private:
void DoSimplePolygons(); void DoSimplePolygons();
void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) const; void FixupFirstLefts1(OutRec* OldOutRec, OutRec* NewOutRec) const;
void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) const; void FixupFirstLefts2(OutRec* OldOutRec, OutRec* NewOutRec) const;
#ifdef use_xyz #ifdef CLIPPERLIB_USE_XYZ
void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2); void SetZ(IntPoint& pt, TEdge& e1, TEdge& e2);
#endif #endif
}; };
@ -519,6 +500,8 @@ class clipperException : public std::exception
} //ClipperLib namespace } //ClipperLib namespace
#ifdef CLIPPERLIB_NAMESPACE_PREFIX
} // namespace CLIPPERLIB_NAMESPACE_PREFIX
#endif // CLIPPERLIB_NAMESPACE_PREFIX
#endif //clipper_hpp #endif //clipper_hpp

View File

@ -1,7 +1,7 @@
// Hackish wrapper around the ClipperLib library to compile the Clipper library with the Z support. // Hackish wrapper around the ClipperLib library to compile the Clipper library with the Z support.
// Enable the Z coordinate support. // Enable the Z coordinate support.
#define use_xyz #define CLIPPERLIB_USE_XYZ
// and let it compile // and let it compile
#include "clipper.cpp" #include "clipper.cpp"

View File

@ -2,17 +2,17 @@
#ifndef clipper_z_hpp #ifndef clipper_z_hpp
#ifdef clipper_hpp #ifdef clipper_hpp
#error "You should include the clipper_z.hpp first" #error "You should include clipper_z.hpp before clipper.hpp"
#endif #endif
#define clipper_z_hpp #define clipper_z_hpp
// Enable the Z coordinate support. // Enable the Z coordinate support.
#define use_xyz #define CLIPPERLIB_USE_XYZ
#include "clipper.hpp" #include "clipper.hpp"
#undef clipper_hpp #undef clipper_hpp
#undef use_xyz #undef CLIPPERLIB_USE_XYZ
#endif // clipper_z_hpp #endif // clipper_z_hpp

View File

@ -132,14 +132,14 @@ template<>
inline void offset(Slic3r::ExPolygon& sh, coord_t distance, const PolygonTag&) inline void offset(Slic3r::ExPolygon& sh, coord_t distance, const PolygonTag&)
{ {
#define DISABLE_BOOST_OFFSET #define DISABLE_BOOST_OFFSET
auto res = Slic3r::offset_ex(sh, distance, ClipperLib::jtSquare); auto res = Slic3r::offset_ex(sh, distance, Slic3r::ClipperLib::jtSquare);
if (!res.empty()) sh = res.front(); if (!res.empty()) sh = res.front();
} }
template<> template<>
inline void offset(Slic3r::Polygon& sh, coord_t distance, const PathTag&) inline void offset(Slic3r::Polygon& sh, coord_t distance, const PathTag&)
{ {
auto res = Slic3r::offset(sh, distance, ClipperLib::jtSquare); auto res = Slic3r::offset(sh, distance, Slic3r::ClipperLib::jtSquare);
if (!res.empty()) sh = res.front(); if (!res.empty()) sh = res.front();
} }

View File

@ -54,7 +54,7 @@ namespace Slic3r {
template<class Tout = double, class = FloatingOnly<Tout>, int...EigenArgs> template<class Tout = double, class = FloatingOnly<Tout>, int...EigenArgs>
inline constexpr Eigen::Matrix<Tout, 2, EigenArgs...> unscaled( inline constexpr Eigen::Matrix<Tout, 2, EigenArgs...> unscaled(
const ClipperLib::IntPoint &v) noexcept const Slic3r::ClipperLib::IntPoint &v) noexcept
{ {
return Eigen::Matrix<Tout, 2, EigenArgs...>{unscaled<Tout>(v.x()), return Eigen::Matrix<Tout, 2, EigenArgs...>{unscaled<Tout>(v.x()),
unscaled<Tout>(v.y())}; unscaled<Tout>(v.y())};
@ -616,7 +616,7 @@ void arrange(ArrangePolygons & arrangables,
const BedT & bed, const BedT & bed,
const ArrangeParams & params) const ArrangeParams & params)
{ {
namespace clppr = ClipperLib; namespace clppr = Slic3r::ClipperLib;
std::vector<Item> items, fixeditems; std::vector<Item> items, fixeditems;
items.reserve(arrangables.size()); items.reserve(arrangables.size());

View File

@ -23,6 +23,8 @@ add_library(libslic3r STATIC
BridgeDetector.hpp BridgeDetector.hpp
Brim.cpp Brim.cpp
Brim.hpp Brim.hpp
clipper.cpp
clipper.hpp
ClipperUtils.cpp ClipperUtils.cpp
ClipperUtils.hpp ClipperUtils.hpp
Config.cpp Config.cpp

View File

@ -8,9 +8,9 @@
#include "Surface.hpp" #include "Surface.hpp"
// import these wherever we're included // import these wherever we're included
using ClipperLib::jtMiter; using Slic3r::ClipperLib::jtMiter;
using ClipperLib::jtRound; using Slic3r::ClipperLib::jtRound;
using ClipperLib::jtSquare; using Slic3r::ClipperLib::jtSquare;
#define CLIPPERUTILS_UNSAFE_OFFSET #define CLIPPERUTILS_UNSAFE_OFFSET

View File

@ -22,12 +22,14 @@
#pragma warning(pop) #pragma warning(pop)
#endif // _MSC_VER #endif // _MSC_VER
namespace ClipperLib { namespace Slic3r {
class PolyNode;
using PolyNodes = std::vector<PolyNode*>;
}
namespace Slic3r { namespace Geometry { namespace ClipperLib {
class PolyNode;
using PolyNodes = std::vector<PolyNode*>;
}
namespace Geometry {
// Generic result of an orientation predicate. // Generic result of an orientation predicate.
enum Orientation enum Orientation
@ -530,6 +532,6 @@ inline bool is_rotation_ninety_degrees(const Vec3d &rotation)
return is_rotation_ninety_degrees(rotation.x()) && is_rotation_ninety_degrees(rotation.y()) && is_rotation_ninety_degrees(rotation.z()); return is_rotation_ninety_degrees(rotation.x()) && is_rotation_ninety_degrees(rotation.y()) && is_rotation_ninety_degrees(rotation.z());
} }
} } } } // namespace Slicer::Geometry
#endif #endif

View File

@ -114,7 +114,7 @@
#include <cereal/types/base_class.hpp> #include <cereal/types/base_class.hpp>
#include <clipper/clipper_z.hpp> #include <clipper/clipper_z.hpp>
#include <clipper/clipper.hpp> #include "clipper.hpp"
#include "BoundingBox.hpp" #include "BoundingBox.hpp"
#include "ClipperUtils.hpp" #include "ClipperUtils.hpp"
#include "Config.hpp" #include "Config.hpp"
@ -129,8 +129,6 @@
#include "libslic3r.h" #include "libslic3r.h"
#include "libslic3r_version.h" #include "libslic3r_version.h"
#include "clipper.hpp"
#include <Shiny/Shiny.h> #include <Shiny/Shiny.h>
#include <admesh/stl.h> #include <admesh/stl.h>

View File

@ -1152,7 +1152,7 @@ template<class It> MultiPolygon merged_pile(It from, It to, int bin_id)
TEST_CASE("Test for bed center distance optimization", "[Nesting], [NestKernels]") TEST_CASE("Test for bed center distance optimization", "[Nesting], [NestKernels]")
{ {
static const constexpr ClipperLib::cInt W = 10000000; static const constexpr Slic3r::ClipperLib::cInt W = 10000000;
// Get the input items and define the bin. // Get the input items and define the bin.
std::vector<RectangleItem> input(9, {W, W}); std::vector<RectangleItem> input(9, {W, W});
@ -1187,7 +1187,7 @@ TEST_CASE("Test for bed center distance optimization", "[Nesting], [NestKernels]
TEST_CASE("Test for biggest bounding box area", "[Nesting], [NestKernels]") TEST_CASE("Test for biggest bounding box area", "[Nesting], [NestKernels]")
{ {
static const constexpr ClipperLib::cInt W = 10000000; static const constexpr Slic3r::ClipperLib::cInt W = 10000000;
static const constexpr size_t N = 100; static const constexpr size_t N = 100;
// Get the input items and define the bin. // Get the input items and define the bin.

View File

@ -2,7 +2,6 @@
%{ %{
#include <xsinit.h> #include <xsinit.h>
#include "clipper.hpp"
#include "libslic3r/ClipperUtils.hpp" #include "libslic3r/ClipperUtils.hpp"
%} %}