Fixes after the merge of changes by @alexrj.
This commit is contained in:
parent
5d18657ac5
commit
126126cc78
14 changed files with 277 additions and 21 deletions
|
@ -709,7 +709,7 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
|||
PolyTreeToExPolygons(polytree, retval);
|
||||
}
|
||||
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
|
||||
void _clipper_pl(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_)
|
||||
{
|
||||
PROFILE_FUNC();
|
||||
|
@ -723,7 +723,7 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
|
|||
ClipperPaths_to_Slic3rMultiPoints(output, retval);
|
||||
}
|
||||
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
|
||||
void _clipper_ln(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_)
|
||||
{
|
||||
// convert Lines to Polylines
|
||||
|
@ -733,7 +733,7 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
|
|||
polylines.push_back(*line);
|
||||
|
||||
// perform operation
|
||||
_clipper(clipType, polylines, clip, &polylines, safety_offset_);
|
||||
_clipper_pl(clipType, polylines, clip, &polylines, safety_offset_);
|
||||
|
||||
// convert Polylines to Lines
|
||||
for (Slic3r::Polylines::const_iterator polyline = polylines.begin(); polyline != polylines.end(); ++polyline)
|
||||
|
@ -750,7 +750,7 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
|||
polylines.push_back(*polygon); // implicit call to split_at_first_point()
|
||||
|
||||
// perform clipping
|
||||
_clipper(clipType, polylines, clip, retval, safety_offset_);
|
||||
_clipper_pl(clipType, polylines, clip, retval, safety_offset_);
|
||||
|
||||
/* If the split_at_first_point() call above happens to split the polygon inside the clipping area
|
||||
we would get two consecutive polylines instead of a single one, so we go through them in order
|
||||
|
@ -796,8 +796,6 @@ void diff(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType*
|
|||
template void diff<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
|
||||
template void diff<Slic3r::Polygons, Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_);
|
||||
template void diff<Slic3r::Polygons, Slic3r::Polylines>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
|
||||
template void diff<Slic3r::Polylines, Slic3r::Polylines>(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
|
||||
template void diff<Slic3r::Lines, Slic3r::Lines>(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_);
|
||||
|
||||
template <class SubjectType, class ResultType>
|
||||
void diff(const SubjectType &subject, const Slic3r::ExPolygons &clip, ResultType* retval, bool safety_offset_)
|
||||
|
@ -850,8 +848,6 @@ void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, Resu
|
|||
template void intersection<Slic3r::Polygons, Slic3r::ExPolygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
|
||||
template void intersection<Slic3r::Polygons, Slic3r::Polygons>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_);
|
||||
template void intersection<Slic3r::Polygons, Slic3r::Polylines>(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
|
||||
template void intersection<Slic3r::Polylines, Slic3r::Polylines>(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
|
||||
template void intersection<Slic3r::Lines, Slic3r::Lines>(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_);
|
||||
|
||||
template <class SubjectType>
|
||||
SubjectType intersection(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_)
|
||||
|
|
|
@ -105,10 +105,10 @@ void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
|||
const Slic3r::Polygons &clip, Slic3r::Polygons* retval, bool safety_offset_);
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polygons &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval, bool safety_offset_);
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Polylines* retval);
|
||||
void _clipper(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Lines* retval);
|
||||
void _clipper_pl(ClipperLib::ClipType clipType, const Slic3r::Polylines &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_);
|
||||
void _clipper_ln(ClipperLib::ClipType clipType, const Slic3r::Lines &subject,
|
||||
const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_);
|
||||
|
||||
template <class SubjectType, class ResultType>
|
||||
void diff(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_ = false);
|
||||
|
@ -121,9 +121,29 @@ Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons &c
|
|||
template <class SubjectType, class ClipType>
|
||||
Slic3r::ExPolygons diff_ex(const SubjectType &subject, const ClipType &clip, bool safety_offset_ = false);
|
||||
|
||||
inline void diff(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_ = false)
|
||||
{
|
||||
_clipper_pl(ClipperLib::ctDifference, subject, clip, retval, safety_offset_);
|
||||
}
|
||||
|
||||
inline void diff(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_ = false)
|
||||
{
|
||||
_clipper_ln(ClipperLib::ctDifference, subject, clip, retval, safety_offset_);
|
||||
}
|
||||
|
||||
template <class SubjectType, class ResultType>
|
||||
void intersection(const SubjectType &subject, const Slic3r::Polygons &clip, ResultType* retval, bool safety_offset_ = false);
|
||||
|
||||
inline void intersection(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, Slic3r::Polylines* retval, bool safety_offset_ = false)
|
||||
{
|
||||
_clipper_pl(ClipperLib::ctIntersection, subject, clip, retval, safety_offset_);
|
||||
}
|
||||
|
||||
inline void intersection(const Slic3r::Lines &subject, const Slic3r::Polygons &clip, Slic3r::Lines* retval, bool safety_offset_ = false)
|
||||
{
|
||||
_clipper_ln(ClipperLib::ctIntersection, subject, clip, retval, safety_offset_);
|
||||
}
|
||||
|
||||
template <class SubjectType>
|
||||
SubjectType intersection(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
|
||||
|
@ -133,6 +153,14 @@ intersection_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, b
|
|||
template <class SubjectType>
|
||||
bool intersects(const SubjectType &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false);
|
||||
|
||||
inline Slic3r::Polylines
|
||||
intersection_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip, bool safety_offset_ = false)
|
||||
{
|
||||
Slic3r::Polylines polylines_out;
|
||||
_clipper_pl(ClipperLib::ctIntersection, subject, clip, &polylines_out, safety_offset_);
|
||||
return polylines_out;
|
||||
}
|
||||
|
||||
void xor_(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, Slic3r::ExPolygons* retval,
|
||||
bool safety_offset_ = false);
|
||||
|
||||
|
|
|
@ -803,7 +803,7 @@ void gcode_spread_points(
|
|||
const Cell &cell = cells[i];
|
||||
acc[cell.idx.y()][cell.idx.x()] = (1.f - cell.fraction_covered) * cell.volume + cell.fraction_covered * cell.area * height_avg;
|
||||
}
|
||||
} else if (simulationType == ExtrusionSimulationSpreadExcess) {
|
||||
} else if (simulationType == Slic3r::ExtrusionSimulationSpreadExcess) {
|
||||
// The volume under the circle does not fit.
|
||||
// 1) Fill the underfilled cells and remove them from the list.
|
||||
float volume_borrowed_total = 0.;
|
||||
|
|
|
@ -13,7 +13,7 @@ enum ExtrusionSimulationType
|
|||
ExtrusionSimulationDontSpread,
|
||||
ExtrisopmSimulationSpreadNotOverfilled,
|
||||
ExtrusionSimulationSpreadFull,
|
||||
ExtrusionSimulationSpreadExcess,
|
||||
ExtrusionSimulationSpreadExcess
|
||||
};
|
||||
|
||||
// An opaque class, to keep the boost stuff away from the header.
|
||||
|
|
|
@ -11,9 +11,6 @@
|
|||
|
||||
namespace Slic3r {
|
||||
|
||||
typedef std::pair<coordf_t,coordf_t> t_layer_height_range;
|
||||
typedef std::map<t_layer_height_range,coordf_t> t_layer_height_ranges;
|
||||
|
||||
class Layer;
|
||||
class PrintRegion;
|
||||
class PrintObject;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "Layer.hpp"
|
||||
#include "Point.hpp"
|
||||
#include "TriangleMesh.hpp"
|
||||
#include "Slicing.hpp"
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
|
|
@ -178,7 +178,7 @@ namespace boost { namespace polygon {
|
|||
static inline Slic3r::Polygon& set_points(Slic3r::Polygon& polygon, iT input_begin, iT input_end) {
|
||||
polygon.points.clear();
|
||||
while (input_begin != input_end) {
|
||||
polygon.points.push_back(Point());
|
||||
polygon.points.push_back(Slic3r::Point());
|
||||
boost::polygon::assign(polygon.points.back(), *input_begin);
|
||||
++input_begin;
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ private:
|
|||
// TODO: call model_object->get_bounding_box() instead of accepting
|
||||
// parameter
|
||||
PrintObject(Print* print, ModelObject* model_object, const BoundingBoxf3 &modobj_bbox);
|
||||
~PrintObject();
|
||||
~PrintObject() {}
|
||||
};
|
||||
|
||||
typedef std::vector<PrintObject*> PrintObjectPtrs;
|
||||
|
|
|
@ -974,7 +974,7 @@ PrintObject::_make_perimeters()
|
|||
|
||||
// check whether a portion of the upper slices falls inside the critical area
|
||||
const Polylines intersection = intersection_pl(
|
||||
upper_layerm_polygons,
|
||||
to_polylines(upper_layerm_polygons),
|
||||
critical_area
|
||||
);
|
||||
|
||||
|
|
44
xs/src/libslic3r/Slicing.hpp
Normal file
44
xs/src/libslic3r/Slicing.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
// Based on implementation by @platsch
|
||||
|
||||
#ifndef slic3r_Slicing_hpp_
|
||||
#define slic3r_Slicing_hpp_
|
||||
|
||||
#include "libslic3r.h"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
struct SlicingParameters
|
||||
{
|
||||
SlicingParameters() { memset(this, 0, sizeof(SlicingParameters)); }
|
||||
|
||||
// The regular layer height, applied for all but the first layer, if not overridden by layer ranges
|
||||
// or by the variable layer thickness table.
|
||||
coordf_t layer_height;
|
||||
|
||||
// Thickness of the first layer. This is either the first print layer thickness if printed without a raft,
|
||||
// or a bridging flow thickness if printed over a non-soluble raft,
|
||||
// or a normal layer height if printed over a soluble raft.
|
||||
coordf_t first_layer_height;
|
||||
|
||||
// If the object is printed over a non-soluble raft, the first layer may be printed with a briding flow.
|
||||
bool first_layer_bridging;
|
||||
|
||||
// Minimum / maximum layer height, to be used for the automatic adaptive layer height algorithm,
|
||||
// or by an interactive layer height editor.
|
||||
coordf_t min_layer_height;
|
||||
coordf_t max_layer_height;
|
||||
|
||||
// Bottom and top of the printed object.
|
||||
// If printed without a raft, object_print_z_min = 0 and object_print_z_max = object height.
|
||||
// Otherwise object_print_z_min is equal to the raft height.
|
||||
coordf_t object_print_z_min;
|
||||
coordf_t object_print_z_max;
|
||||
};
|
||||
|
||||
typedef std::pair<coordf_t,coordf_t> t_layer_height_range;
|
||||
typedef std::map<t_layer_height_range,coordf_t> t_layer_height_ranges;
|
||||
|
||||
}; // namespace Slic3r
|
||||
|
||||
#endif /* slic3r_Slicing_hpp_ */
|
149
xs/src/libslic3r/SlicingAdaptive.cpp
Normal file
149
xs/src/libslic3r/SlicingAdaptive.cpp
Normal file
|
@ -0,0 +1,149 @@
|
|||
#include "libslic3r.h"
|
||||
#include "TriangleMesh.hpp"
|
||||
#include "SlicingAdaptive.hpp"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
void SlicingAdaptive::clear()
|
||||
{
|
||||
m_meshes.clear();
|
||||
m_faces.clear();
|
||||
m_face_normal_z.clear();
|
||||
}
|
||||
|
||||
std::pair<float, float> face_z_span(const stl_facet *f)
|
||||
{
|
||||
return std::pair<float, float>(
|
||||
std::min(std::min(f->vertex[0].z, f->vertex[1].z), f->vertex[2].z),
|
||||
std::max(std::max(f->vertex[0].z, f->vertex[1].z), f->vertex[2].z));
|
||||
}
|
||||
|
||||
void SlicingAdaptive::prepare()
|
||||
{
|
||||
// 1) Collect faces of all meshes.
|
||||
{
|
||||
int nfaces_total = 0;
|
||||
for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh)
|
||||
nfaces_total += (*it_mesh)->stl.stats.number_of_facets;
|
||||
m_faces.reserve(nfaces_total);
|
||||
}
|
||||
m_max_z = 0;
|
||||
for (std::vector<const TriangleMesh*>::const_iterator it_mesh = m_meshes.begin(); it_mesh != m_meshes.end(); ++ it_mesh) {
|
||||
const stl_facet *faces = (*it_mesh)->stl.facet_start;
|
||||
int nfaces = (*it_mesh)->stl.stats.number_of_facets;
|
||||
for (int i = 0; i < nfaces; ++ i) {
|
||||
const stl_facet *facet = faces + i;
|
||||
m_faces.push_back(facet);
|
||||
m_max_z = std::max(std::max(m_max_z, facet->vertex[0].z), std::max(facet->vertex[1].z, facet->vertex[2].z));
|
||||
}
|
||||
}
|
||||
|
||||
// 2) Sort faces lexicographically by their Z span.
|
||||
std::sort(m_faces.begin(), m_faces.end(), [](const stl_facet *f1, const stl_facet *f2) {
|
||||
std::pair<float, float> span1 = face_z_span(f1);
|
||||
std::pair<float, float> span2 = face_z_span(f2);
|
||||
return span1 < span2;
|
||||
});
|
||||
|
||||
// 3) Generate Z components of the facet normals.
|
||||
m_face_normal_z.assign(m_faces.size(), 0.f);
|
||||
for (size_t iface = 0; iface < m_faces.size(); ++ iface)
|
||||
m_face_normal_z[iface] = m_faces[iface]->normal.z;
|
||||
}
|
||||
|
||||
float SlicingAdaptive::cusp_height(float z, float cusp_value, int ¤t_facet)
|
||||
{
|
||||
float height = m_layer_height_max;
|
||||
bool first_hit = false;
|
||||
|
||||
// find all facets intersecting the slice-layer
|
||||
int ordered_id = current_facet;
|
||||
for (; ordered_id < int(m_faces.size()); ++ ordered_id) {
|
||||
std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]);
|
||||
// facet's minimum is higher than slice_z -> end loop
|
||||
if (zspan.first >= z)
|
||||
break;
|
||||
// facet's maximum is higher than slice_z -> store the first event for next cusp_height call to begin at this point
|
||||
if (zspan.second > z) {
|
||||
// first event?
|
||||
if (! first_hit) {
|
||||
first_hit = true;
|
||||
current_facet = ordered_id;
|
||||
}
|
||||
// skip touching facets which could otherwise cause small cusp values
|
||||
if (zspan.second <= z + EPSILON)
|
||||
continue;
|
||||
// compute cusp-height for this facet and store minimum of all heights
|
||||
float normal_z = m_face_normal_z[ordered_id];
|
||||
height = std::min(height, (normal_z == 0) ? 9999 : abs(cusp_value / normal_z));
|
||||
}
|
||||
}
|
||||
|
||||
// lower height limit due to printer capabilities
|
||||
height = std::max(height, m_layer_height_min);
|
||||
|
||||
// check for sloped facets inside the determined layer and correct height if necessary
|
||||
if (height > m_layer_height_min) {
|
||||
for (; ordered_id < int(m_faces.size()); ++ ordered_id) {
|
||||
std::pair<float, float> zspan = face_z_span(m_faces[ordered_id]);
|
||||
// facet's minimum is higher than slice_z + height -> end loop
|
||||
if (zspan.first >= z + height)
|
||||
break;
|
||||
|
||||
// skip touching facets which could otherwise cause small cusp values
|
||||
if (zspan.second <= z + EPSILON)
|
||||
continue;
|
||||
|
||||
// Compute cusp-height for this facet and check against height.
|
||||
float normal_z = m_face_normal_z[ordered_id];
|
||||
float cusp = (normal_z == 0) ? 9999 : abs(cusp_value / normal_z);
|
||||
|
||||
float z_diff = zspan.first - z;
|
||||
|
||||
// handle horizontal facets
|
||||
if (m_face_normal_z[ordered_id] > 0.999) {
|
||||
// Slic3r::debugf "cusp computation, height is reduced from %f", $height;
|
||||
height = z_diff;
|
||||
// Slic3r::debugf "to %f due to near horizontal facet\n", $height;
|
||||
} else if (cusp > z_diff) {
|
||||
if (cusp < height) {
|
||||
// Slic3r::debugf "cusp computation, height is reduced from %f", $height;
|
||||
height = cusp;
|
||||
// Slic3r::debugf "to %f due to new cusp height\n", $height;
|
||||
}
|
||||
} else {
|
||||
// Slic3r::debugf "cusp computation, height is reduced from %f", $height;
|
||||
height = z_diff;
|
||||
// Slic3r::debugf "to z-diff: %f\n", $height;
|
||||
}
|
||||
}
|
||||
// lower height limit due to printer capabilities again
|
||||
height = std::max(height, m_layer_height_min);
|
||||
}
|
||||
|
||||
// Slic3r::debugf "cusp computation, layer-bottom at z:%f, cusp_value:%f, resulting layer height:%f\n", unscale $z, $cusp_value, $height;
|
||||
return height;
|
||||
}
|
||||
|
||||
// Returns the distance to the next horizontal facet in Z-dir
|
||||
// to consider horizontal object features in slice thickness
|
||||
float SlicingAdaptive::horizontal_facet_distance(float z)
|
||||
{
|
||||
for (size_t i = 0; i < m_faces.size(); ++ i) {
|
||||
std::pair<float, float> zspan = face_z_span(m_faces[i]);
|
||||
// facet's minimum is higher than max forward distance -> end loop
|
||||
if (zspan.first > z + m_layer_height_max)
|
||||
break;
|
||||
// min_z == max_z -> horizontal facet
|
||||
if (zspan.first > z && zspan.first == zspan.second)
|
||||
return zspan.first - z;
|
||||
}
|
||||
|
||||
// objects maximum?
|
||||
return (z + m_layer_height_max > m_max_z) ?
|
||||
std::max<float>(m_max_z - z, 0.f) :
|
||||
m_layer_height_max;
|
||||
}
|
||||
|
||||
}; // namespace Slic3r
|
38
xs/src/libslic3r/SlicingAdaptive.hpp
Normal file
38
xs/src/libslic3r/SlicingAdaptive.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Based on implementation by @platsch
|
||||
|
||||
#ifndef slic3r_SlicingAdaptive_hpp_
|
||||
#define slic3r_SlicingAdaptive_hpp_
|
||||
|
||||
#include "Slicing.hpp"
|
||||
#include "admesh/stl.h"
|
||||
|
||||
namespace Slic3r
|
||||
{
|
||||
|
||||
class TriangleMesh;
|
||||
|
||||
class SlicingAdaptive
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
void set_layer_height_range(float min, float max) { m_layer_height_min = min; m_layer_height_max = max; }
|
||||
void add_mesh(const TriangleMesh *mesh) { m_meshes.push_back(mesh); }
|
||||
void prepare();
|
||||
float cusp_height(float z, float cusp_value, int ¤t_facet);
|
||||
float horizontal_facet_distance(float z);
|
||||
|
||||
protected:
|
||||
float m_layer_height_min;
|
||||
float m_layer_height_max;
|
||||
float m_max_z;
|
||||
|
||||
std::vector<const TriangleMesh*> m_meshes;
|
||||
// Collected faces of all meshes, sorted by raising Z of the bottom most face.
|
||||
std::vector<const stl_facet*> m_faces;
|
||||
// Z component of face normals, normalized.
|
||||
std::vector<float> m_face_normal_z;
|
||||
};
|
||||
|
||||
}; // namespace Slic3r
|
||||
|
||||
#endif /* slic3r_SlicingAdaptive_hpp_ */
|
|
@ -8,7 +8,6 @@
|
|||
#include "EdgeGrid.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <unordered_set>
|
||||
|
@ -21,6 +20,8 @@
|
|||
#include "SVG.hpp"
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
// Increment used to reach MARGIN in steps to avoid trespassing thin objects
|
||||
|
|
|
@ -163,4 +163,6 @@ SV* polynode2perl(const ClipperLib::PolyNode& node);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
using namespace Slic3r;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue