mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-24 15:13:58 -06:00
New custom backend for libnest2d using libslic3r types
Adapted to new clipper->eigen mod
This commit is contained in:
parent
7112ac61b6
commit
ad19ab219d
21 changed files with 656 additions and 765 deletions
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "BoundingBox.hpp"
|
||||
|
||||
#include <libnest2d/backends/clipper/geometries.hpp>
|
||||
#include <libnest2d/backends/libslic3r/geometries.hpp>
|
||||
#include <libnest2d/optimizers/nlopt/subplex.hpp>
|
||||
#include <libnest2d/placers/nfpplacer.hpp>
|
||||
#include <libnest2d/selections/firstfit.hpp>
|
||||
|
@ -63,14 +63,13 @@ inline constexpr Eigen::Matrix<Tout, 2, EigenArgs...> unscaled(
|
|||
namespace arrangement {
|
||||
|
||||
using namespace libnest2d;
|
||||
namespace clppr = ClipperLib;
|
||||
|
||||
// Get the libnest2d types for clipper backend
|
||||
using Item = _Item<clppr::Polygon>;
|
||||
using Box = _Box<clppr::IntPoint>;
|
||||
using Circle = _Circle<clppr::IntPoint>;
|
||||
using Segment = _Segment<clppr::IntPoint>;
|
||||
using MultiPolygon = TMultiShape<clppr::Polygon>;
|
||||
using Item = _Item<ExPolygon>;
|
||||
using Box = _Box<Point>;
|
||||
using Circle = _Circle<Point>;
|
||||
using Segment = _Segment<Point>;
|
||||
using MultiPolygon = ExPolygons;
|
||||
|
||||
// Summon the spatial indexing facilities from boost
|
||||
namespace bgi = boost::geometry::index;
|
||||
|
@ -127,8 +126,8 @@ template<class TBin>
|
|||
class AutoArranger {
|
||||
public:
|
||||
// Useful type shortcuts...
|
||||
using Placer = typename placers::_NofitPolyPlacer<clppr::Polygon, TBin>;
|
||||
using Selector = selections::_FirstFitSelection<clppr::Polygon>;
|
||||
using Placer = typename placers::_NofitPolyPlacer<ExPolygon, TBin>;
|
||||
using Selector = selections::_FirstFitSelection<ExPolygon>;
|
||||
using Packer = _Nester<Placer, Selector>;
|
||||
using PConfig = typename Packer::PlacementConfig;
|
||||
using Distance = TCoord<PointImpl>;
|
||||
|
@ -168,7 +167,7 @@ protected:
|
|||
// as it possibly can be but at the same time, it has to provide
|
||||
// reasonable results.
|
||||
std::tuple<double /*score*/, Box /*farthest point from bin center*/>
|
||||
objfunc(const Item &item, const clppr::IntPoint &bincenter)
|
||||
objfunc(const Item &item, const Point &bincenter)
|
||||
{
|
||||
const double bin_area = m_bin_area;
|
||||
const SpatIndex& spatindex = m_rtree;
|
||||
|
@ -220,12 +219,12 @@ protected:
|
|||
|
||||
switch (compute_case) {
|
||||
case BIG_ITEM: {
|
||||
const clppr::IntPoint& minc = ibb.minCorner(); // bottom left corner
|
||||
const clppr::IntPoint& maxc = ibb.maxCorner(); // top right corner
|
||||
const Point& minc = ibb.minCorner(); // bottom left corner
|
||||
const Point& maxc = ibb.maxCorner(); // top right corner
|
||||
|
||||
// top left and bottom right corners
|
||||
clppr::IntPoint top_left{getX(minc), getY(maxc)};
|
||||
clppr::IntPoint bottom_right{getX(maxc), getY(minc)};
|
||||
Point top_left{getX(minc), getY(maxc)};
|
||||
Point bottom_right{getX(maxc), getY(minc)};
|
||||
|
||||
// Now the distance of the gravity center will be calculated to the
|
||||
// five anchor points and the smallest will be chosen.
|
||||
|
@ -452,7 +451,7 @@ template<> std::function<double(const Item&)> AutoArranger<Circle>::get_objfn()
|
|||
// Specialization for a generalized polygon.
|
||||
// Warning: this is unfinished business. It may or may not work.
|
||||
template<>
|
||||
std::function<double(const Item &)> AutoArranger<clppr::Polygon>::get_objfn()
|
||||
std::function<double(const Item &)> AutoArranger<ExPolygon>::get_objfn()
|
||||
{
|
||||
auto bincenter = sl::boundingBox(m_bin).center();
|
||||
return [this, bincenter](const Item &item) {
|
||||
|
@ -521,7 +520,7 @@ void _arrange(
|
|||
|
||||
inline Box to_nestbin(const BoundingBox &bb) { return Box{{bb.min(X), bb.min(Y)}, {bb.max(X), bb.max(Y)}};}
|
||||
inline Circle to_nestbin(const CircleBed &c) { return Circle({c.center()(0), c.center()(1)}, c.radius()); }
|
||||
inline clppr::Polygon to_nestbin(const Polygon &p) { return sl::create<clppr::Polygon>(Slic3rMultiPoint_to_ClipperPath(p)); }
|
||||
inline ExPolygon to_nestbin(const Polygon &p) { return ExPolygon{p}; }
|
||||
inline Box to_nestbin(const InfiniteBed &bed) { return Box::infinite({bed.center.x(), bed.center.y()}); }
|
||||
|
||||
inline coord_t width(const BoundingBox& box) { return box.max.x() - box.min.x(); }
|
||||
|
@ -568,19 +567,12 @@ static void process_arrangeable(const ArrangePolygon &arrpoly,
|
|||
const Vec2crd &offs = arrpoly.translation;
|
||||
double rotation = arrpoly.rotation;
|
||||
|
||||
if (p.is_counter_clockwise()) p.reverse();
|
||||
|
||||
clppr::Polygon clpath(Slic3rMultiPoint_to_ClipperPath(p));
|
||||
|
||||
// This fixes:
|
||||
// https://github.com/prusa3d/PrusaSlicer/issues/2209
|
||||
if (clpath.Contour.size() < 3)
|
||||
if (p.points.size() < 3)
|
||||
return;
|
||||
|
||||
auto firstp = clpath.Contour.front();
|
||||
clpath.Contour.emplace_back(firstp);
|
||||
|
||||
outp.emplace_back(std::move(clpath));
|
||||
outp.emplace_back(std::move(p));
|
||||
outp.back().rotation(rotation);
|
||||
outp.back().translation({offs.x(), offs.y()});
|
||||
outp.back().binId(arrpoly.bed_idx);
|
||||
|
@ -643,7 +635,7 @@ void arrange(ArrangePolygons & arrangables,
|
|||
_arrange(items, fixeditems, to_nestbin(bed), params, pri, cfn);
|
||||
|
||||
for(size_t i = 0; i < items.size(); ++i) {
|
||||
clppr::IntPoint tr = items[i].translation();
|
||||
Point tr = items[i].translation();
|
||||
arrangables[i].translation = {coord_t(tr.x()), coord_t(tr.y())};
|
||||
arrangables[i].rotation = items[i].rotation();
|
||||
arrangables[i].bed_idx = items[i].binId();
|
||||
|
|
|
@ -360,6 +360,8 @@ extern std::vector<BoundingBox> get_extents_vector(const ExPolygons &polygons);
|
|||
extern bool remove_sticks(ExPolygon &poly);
|
||||
extern void keep_largest_contour_only(ExPolygons &polygons);
|
||||
|
||||
inline double area(const ExPolygon &poly) { return poly.area(); }
|
||||
|
||||
inline double area(const ExPolygons &polys)
|
||||
{
|
||||
double s = 0.;
|
||||
|
|
|
@ -72,6 +72,16 @@ public:
|
|||
// Projection of a point onto the polygon.
|
||||
Point point_projection(const Point &point) const;
|
||||
std::vector<float> parameter_by_length() const;
|
||||
|
||||
using iterator = Points::iterator;
|
||||
using const_iterator = Points::const_iterator;
|
||||
|
||||
inline auto begin() { return points.begin(); }
|
||||
inline auto begin() const { return points.begin(); }
|
||||
inline auto end() { return points.end(); }
|
||||
inline auto end() const { return points.end(); }
|
||||
inline auto cbegin() const { return points.begin(); }
|
||||
inline auto cend() const { return points.end(); }
|
||||
};
|
||||
|
||||
inline bool operator==(const Polygon &lhs, const Polygon &rhs) { return lhs.points == rhs.points; }
|
||||
|
@ -90,6 +100,8 @@ inline double total_length(const Polygons &polylines) {
|
|||
return total;
|
||||
}
|
||||
|
||||
inline double area(const Polygon &poly) { return poly.area(); }
|
||||
|
||||
inline double area(const Polygons &polys)
|
||||
{
|
||||
double s = 0.;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <libslic3r/SLA/RasterBase.hpp>
|
||||
#include "libslic3r/ExPolygon.hpp"
|
||||
#include "libslic3r/MTUtils.hpp"
|
||||
#include <libnest2d/backends/clipper/clipper_polygon.hpp>
|
||||
|
||||
// For rasterizing
|
||||
#include <agg/agg_basics.h>
|
||||
|
@ -21,10 +20,7 @@
|
|||
namespace Slic3r {
|
||||
|
||||
inline const Polygon& contour(const ExPolygon& p) { return p.contour; }
|
||||
inline const ClipperLib::Path& contour(const ClipperLib::Polygon& p) { return p.Contour; }
|
||||
|
||||
inline const Polygons& holes(const ExPolygon& p) { return p.holes; }
|
||||
inline const ClipperLib::Paths& holes(const ClipperLib::Polygon& p) { return p.Holes; }
|
||||
|
||||
namespace sla {
|
||||
|
||||
|
@ -77,8 +73,6 @@ protected:
|
|||
double getPx(const Point &p) { return p(0) * m_pxdim_scaled.w_mm; }
|
||||
double getPy(const Point &p) { return p(1) * m_pxdim_scaled.h_mm; }
|
||||
agg::path_storage to_path(const Polygon &poly) { return to_path(poly.points); }
|
||||
double getPx(const ClipperLib::IntPoint &p) { return p.x() * m_pxdim_scaled.w_mm; }
|
||||
double getPy(const ClipperLib::IntPoint& p) { return p.y() * m_pxdim_scaled.h_mm; }
|
||||
|
||||
template<class PointVec> agg::path_storage _to_path(const PointVec& v)
|
||||
{
|
||||
|
@ -168,7 +162,6 @@ public:
|
|||
}
|
||||
|
||||
void draw(const ExPolygon &poly) override { _draw(poly); }
|
||||
void draw(const ClipperLib::Polygon &poly) override { _draw(poly); }
|
||||
|
||||
EncodedRaster encode(RasterEncoder encoder) const override
|
||||
{
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
#include <libslic3r/ExPolygon.hpp>
|
||||
#include <libslic3r/SLA/Concurrency.hpp>
|
||||
|
||||
namespace ClipperLib { struct Polygon; }
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
template<class T> using uqptr = std::unique_ptr<T>;
|
||||
|
@ -92,7 +90,6 @@ public:
|
|||
|
||||
/// Draw a polygon with holes.
|
||||
virtual void draw(const ExPolygon& poly) = 0;
|
||||
virtual void draw(const ClipperLib::Polygon& poly) = 0;
|
||||
|
||||
/// Get the resolution of the raster.
|
||||
virtual Resolution resolution() const = 0;
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "ExPolygonCollection.hpp"
|
||||
#include "libslic3r.h"
|
||||
|
||||
#include "libnest2d/backends/clipper/geometries.hpp"
|
||||
#include "libnest2d/backends/libslic3r/geometries.hpp"
|
||||
#include "libnest2d/utils/rotcalipers.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
@ -400,7 +400,7 @@ std::vector<Vec2f> sample_expolygon(const ExPolygons &expolys, float samples_per
|
|||
void sample_expolygon_boundary(const ExPolygon & expoly,
|
||||
float samples_per_mm,
|
||||
std::vector<Vec2f> &out,
|
||||
std::mt19937 & rng)
|
||||
std::mt19937 & /*rng*/)
|
||||
{
|
||||
double point_stepping_scaled = scale_(1.f) / samples_per_mm;
|
||||
for (size_t i_contour = 0; i_contour <= expoly.holes.size(); ++ i_contour) {
|
||||
|
@ -553,8 +553,7 @@ void SupportPointGenerator::uniformly_cover(const ExPolygons& islands, Structure
|
|||
// auto bb = get_extents(islands);
|
||||
|
||||
if (flags & icfIsNew) {
|
||||
auto chull_ex = ExPolygonCollection{islands}.convex_hull();
|
||||
auto chull = Slic3rMultiPoint_to_ClipperPath(chull_ex);
|
||||
auto chull = ExPolygonCollection{islands}.convex_hull();
|
||||
auto rotbox = libnest2d::minAreaBoundingBox(chull);
|
||||
Vec2d bbdim = {unscaled(rotbox.width()), unscaled(rotbox.height())};
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "Point.hpp"
|
||||
#include "MTUtils.hpp"
|
||||
#include "Zipper.hpp"
|
||||
#include <libnest2d/backends/clipper/clipper_polygon.hpp>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
|
@ -483,7 +482,7 @@ public:
|
|||
// The collection of slice records for the current level.
|
||||
std::vector<std::reference_wrapper<const SliceRecord>> m_slices;
|
||||
|
||||
std::vector<ClipperLib::Polygon> m_transformed_slices;
|
||||
ExPolygons m_transformed_slices;
|
||||
|
||||
template<class Container> void transformed_slices(Container&& c)
|
||||
{
|
||||
|
@ -507,7 +506,7 @@ public:
|
|||
|
||||
auto slices() const -> const decltype (m_slices)& { return m_slices; }
|
||||
|
||||
const std::vector<ClipperLib::Polygon> & transformed_slices() const {
|
||||
const ExPolygons & transformed_slices() const {
|
||||
return m_transformed_slices;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
|
||||
#include <libslic3r/ClipperUtils.hpp>
|
||||
|
||||
// For geometry algorithms with native Clipper types (no copies and conversions)
|
||||
#include <libnest2d/backends/clipper/geometries.hpp>
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
|
||||
#include "I18N.hpp"
|
||||
|
@ -717,55 +714,49 @@ void SLAPrint::Steps::slice_supports(SLAPrintObject &po) {
|
|||
report_status(-2, "", SlicingStatus::RELOAD_SLA_PREVIEW);
|
||||
}
|
||||
|
||||
using ClipperPoint = ClipperLib::IntPoint;
|
||||
using ClipperPolygon = ClipperLib::Polygon; // see clipper_polygon.hpp in libnest2d
|
||||
using ClipperPolygons = std::vector<ClipperPolygon>;
|
||||
//static ClipperPolygons polyunion(const ClipperPolygons &subjects)
|
||||
//{
|
||||
// ClipperLib::Clipper clipper;
|
||||
|
||||
static ClipperPolygons polyunion(const ClipperPolygons &subjects)
|
||||
{
|
||||
ClipperLib::Clipper clipper;
|
||||
// bool closed = true;
|
||||
|
||||
bool closed = true;
|
||||
// for(auto& path : subjects) {
|
||||
// clipper.AddPath(path.Contour, ClipperLib::ptSubject, closed);
|
||||
// clipper.AddPaths(path.Holes, ClipperLib::ptSubject, closed);
|
||||
// }
|
||||
|
||||
for(auto& path : subjects) {
|
||||
clipper.AddPath(path.Contour, ClipperLib::ptSubject, closed);
|
||||
clipper.AddPaths(path.Holes, ClipperLib::ptSubject, closed);
|
||||
}
|
||||
// auto mode = ClipperLib::pftPositive;
|
||||
|
||||
auto mode = ClipperLib::pftPositive;
|
||||
// return libnest2d::clipper_execute(clipper, ClipperLib::ctUnion, mode, mode);
|
||||
//}
|
||||
|
||||
return libnest2d::clipper_execute(clipper, ClipperLib::ctUnion, mode, mode);
|
||||
}
|
||||
//static ClipperPolygons polydiff(const ClipperPolygons &subjects, const ClipperPolygons& clips)
|
||||
//{
|
||||
// ClipperLib::Clipper clipper;
|
||||
|
||||
static ClipperPolygons polydiff(const ClipperPolygons &subjects, const ClipperPolygons& clips)
|
||||
{
|
||||
ClipperLib::Clipper clipper;
|
||||
// bool closed = true;
|
||||
|
||||
bool closed = true;
|
||||
// for(auto& path : subjects) {
|
||||
// clipper.AddPath(path.Contour, ClipperLib::ptSubject, closed);
|
||||
// clipper.AddPaths(path.Holes, ClipperLib::ptSubject, closed);
|
||||
// }
|
||||
|
||||
for(auto& path : subjects) {
|
||||
clipper.AddPath(path.Contour, ClipperLib::ptSubject, closed);
|
||||
clipper.AddPaths(path.Holes, ClipperLib::ptSubject, closed);
|
||||
}
|
||||
// for(auto& path : clips) {
|
||||
// clipper.AddPath(path.Contour, ClipperLib::ptClip, closed);
|
||||
// clipper.AddPaths(path.Holes, ClipperLib::ptClip, closed);
|
||||
// }
|
||||
|
||||
for(auto& path : clips) {
|
||||
clipper.AddPath(path.Contour, ClipperLib::ptClip, closed);
|
||||
clipper.AddPaths(path.Holes, ClipperLib::ptClip, closed);
|
||||
}
|
||||
// auto mode = ClipperLib::pftPositive;
|
||||
|
||||
auto mode = ClipperLib::pftPositive;
|
||||
|
||||
return libnest2d::clipper_execute(clipper, ClipperLib::ctDifference, mode, mode);
|
||||
}
|
||||
// return libnest2d::clipper_execute(clipper, ClipperLib::ctDifference, mode, mode);
|
||||
//}
|
||||
|
||||
// get polygons for all instances in the object
|
||||
static ClipperPolygons get_all_polygons(const SliceRecord& record, SliceOrigin o)
|
||||
static ExPolygons get_all_polygons(const SliceRecord& record, SliceOrigin o)
|
||||
{
|
||||
namespace sl = libnest2d::sl;
|
||||
|
||||
if (!record.print_obj()) return {};
|
||||
|
||||
ClipperPolygons polygons;
|
||||
ExPolygons polygons;
|
||||
auto &input_polygons = record.get_slice(o);
|
||||
auto &instances = record.print_obj()->instances();
|
||||
bool is_lefthanded = record.print_obj()->is_left_handed();
|
||||
|
@ -776,43 +767,42 @@ static ClipperPolygons get_all_polygons(const SliceRecord& record, SliceOrigin o
|
|||
|
||||
for (size_t i = 0; i < instances.size(); ++i)
|
||||
{
|
||||
ClipperPolygon poly;
|
||||
ExPolygon poly;
|
||||
|
||||
// We need to reverse if is_lefthanded is true but
|
||||
bool needreverse = is_lefthanded;
|
||||
|
||||
// should be a move
|
||||
poly.Contour.reserve(polygon.contour.size() + 1);
|
||||
poly.contour.points.reserve(polygon.contour.size() + 1);
|
||||
|
||||
auto& cntr = polygon.contour.points;
|
||||
if(needreverse)
|
||||
for(auto it = cntr.rbegin(); it != cntr.rend(); ++it)
|
||||
poly.Contour.emplace_back(it->x(), it->y());
|
||||
poly.contour.points.emplace_back(it->x(), it->y());
|
||||
else
|
||||
for(auto& p : cntr)
|
||||
poly.Contour.emplace_back(p.x(), p.y());
|
||||
poly.contour.points.emplace_back(p.x(), p.y());
|
||||
|
||||
for(auto& h : polygon.holes) {
|
||||
poly.Holes.emplace_back();
|
||||
auto& hole = poly.Holes.back();
|
||||
hole.reserve(h.points.size() + 1);
|
||||
poly.holes.emplace_back();
|
||||
auto& hole = poly.holes.back();
|
||||
hole.points.reserve(h.points.size() + 1);
|
||||
|
||||
if(needreverse)
|
||||
for(auto it = h.points.rbegin(); it != h.points.rend(); ++it)
|
||||
hole.emplace_back(it->x(), it->y());
|
||||
hole.points.emplace_back(it->x(), it->y());
|
||||
else
|
||||
for(auto& p : h.points)
|
||||
hole.emplace_back(p.x(), p.y());
|
||||
hole.points.emplace_back(p.x(), p.y());
|
||||
}
|
||||
|
||||
if(is_lefthanded) {
|
||||
for(auto& p : poly.Contour) p.x() = -p.x();
|
||||
for(auto& h : poly.Holes) for(auto& p : h) p.x() = -p.x();
|
||||
for(auto& p : poly.contour) p.x() = -p.x();
|
||||
for(auto& h : poly.holes) for(auto& p : h) p.x() = -p.x();
|
||||
}
|
||||
|
||||
sl::rotate(poly, double(instances[i].rotation));
|
||||
sl::translate(poly, ClipperPoint{instances[i].shift.x(),
|
||||
instances[i].shift.y()});
|
||||
poly.rotate(double(instances[i].rotation));
|
||||
poly.translate(Point{instances[i].shift.x(), instances[i].shift.y()});
|
||||
|
||||
polygons.emplace_back(std::move(poly));
|
||||
}
|
||||
|
@ -878,9 +868,6 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
|||
|
||||
print_statistics.clear();
|
||||
|
||||
// libnest calculates positive area for clockwise polygons, Slic3r is in counter-clockwise
|
||||
auto areafn = [](const ClipperPolygon& poly) { return - libnest2d::sl::area(poly); };
|
||||
|
||||
const double area_fill = printer_config.area_fill.getFloat()*0.01;// 0.5 (50%);
|
||||
const double fast_tilt = printer_config.fast_tilt_time.getFloat();// 5.0;
|
||||
const double slow_tilt = printer_config.slow_tilt_time.getFloat();// 8.0;
|
||||
|
@ -913,7 +900,7 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
|||
// Going to parallel:
|
||||
auto printlayerfn = [this,
|
||||
// functions and read only vars
|
||||
areafn, area_fill, display_area, exp_time, init_exp_time, fast_tilt, slow_tilt, delta_fade_time,
|
||||
area_fill, display_area, exp_time, init_exp_time, fast_tilt, slow_tilt, delta_fade_time,
|
||||
|
||||
// write vars
|
||||
&mutex, &models_volume, &supports_volume, &estim_time, &slow_layers,
|
||||
|
@ -931,8 +918,8 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
|||
|
||||
// Calculation of the consumed material
|
||||
|
||||
ClipperPolygons model_polygons;
|
||||
ClipperPolygons supports_polygons;
|
||||
ExPolygons model_polygons;
|
||||
ExPolygons supports_polygons;
|
||||
|
||||
size_t c = std::accumulate(layer.slices().begin(),
|
||||
layer.slices().end(),
|
||||
|
@ -954,44 +941,44 @@ void SLAPrint::Steps::merge_slices_and_eval_stats() {
|
|||
|
||||
for(const SliceRecord& record : layer.slices()) {
|
||||
|
||||
ClipperPolygons modelslices = get_all_polygons(record, soModel);
|
||||
for(ClipperPolygon& p_tmp : modelslices) model_polygons.emplace_back(std::move(p_tmp));
|
||||
ExPolygons modelslices = get_all_polygons(record, soModel);
|
||||
for(ExPolygon& p_tmp : modelslices) model_polygons.emplace_back(std::move(p_tmp));
|
||||
|
||||
ClipperPolygons supportslices = get_all_polygons(record, soSupport);
|
||||
for(ClipperPolygon& p_tmp : supportslices) supports_polygons.emplace_back(std::move(p_tmp));
|
||||
ExPolygons supportslices = get_all_polygons(record, soSupport);
|
||||
for(ExPolygon& p_tmp : supportslices) supports_polygons.emplace_back(std::move(p_tmp));
|
||||
|
||||
}
|
||||
|
||||
model_polygons = polyunion(model_polygons);
|
||||
model_polygons = union_ex(model_polygons);
|
||||
double layer_model_area = 0;
|
||||
for (const ClipperPolygon& polygon : model_polygons)
|
||||
layer_model_area += areafn(polygon);
|
||||
for (const ExPolygon& polygon : model_polygons)
|
||||
layer_model_area += area(polygon);
|
||||
|
||||
if (layer_model_area < 0 || layer_model_area > 0) {
|
||||
Lock lck(mutex); models_volume += layer_model_area * l_height;
|
||||
}
|
||||
|
||||
if(!supports_polygons.empty()) {
|
||||
if(model_polygons.empty()) supports_polygons = polyunion(supports_polygons);
|
||||
else supports_polygons = polydiff(supports_polygons, model_polygons);
|
||||
if(model_polygons.empty()) supports_polygons = union_ex(supports_polygons);
|
||||
else supports_polygons = diff_ex(supports_polygons, model_polygons);
|
||||
// allegedly, union of subject is done withing the diff according to the pftPositive polyFillType
|
||||
}
|
||||
|
||||
double layer_support_area = 0;
|
||||
for (const ClipperPolygon& polygon : supports_polygons)
|
||||
layer_support_area += areafn(polygon);
|
||||
for (const ExPolygon& polygon : supports_polygons)
|
||||
layer_support_area += area(polygon);
|
||||
|
||||
if (layer_support_area < 0 || layer_support_area > 0) {
|
||||
Lock lck(mutex); supports_volume += layer_support_area * l_height;
|
||||
}
|
||||
|
||||
// Here we can save the expensively calculated polygons for printing
|
||||
ClipperPolygons trslices;
|
||||
ExPolygons trslices;
|
||||
trslices.reserve(model_polygons.size() + supports_polygons.size());
|
||||
for(ClipperPolygon& poly : model_polygons) trslices.emplace_back(std::move(poly));
|
||||
for(ClipperPolygon& poly : supports_polygons) trslices.emplace_back(std::move(poly));
|
||||
for(ExPolygon& poly : model_polygons) trslices.emplace_back(std::move(poly));
|
||||
for(ExPolygon& poly : supports_polygons) trslices.emplace_back(std::move(poly));
|
||||
|
||||
layer.transformed_slices(polyunion(trslices));
|
||||
layer.transformed_slices(union_ex(trslices));
|
||||
|
||||
// Calculation of the slow and fast layers to the future controlling those values on FW
|
||||
|
||||
|
@ -1074,7 +1061,7 @@ void SLAPrint::Steps::rasterize()
|
|||
PrintLayer& printlayer = m_print->m_printer_input[idx];
|
||||
if(canceled()) return;
|
||||
|
||||
for (const ClipperLib::Polygon& poly : printlayer.transformed_slices())
|
||||
for (const ExPolygon& poly : printlayer.transformed_slices())
|
||||
raster.draw(poly);
|
||||
|
||||
// Status indication guarded with the spinlock
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue