Added concentric infill generated using Arachne.
This commit is contained in:
parent
ac23a369d5
commit
454e6496ce
@ -8,10 +8,12 @@
|
|||||||
#include "../Print.hpp"
|
#include "../Print.hpp"
|
||||||
#include "../PrintConfig.hpp"
|
#include "../PrintConfig.hpp"
|
||||||
#include "../Surface.hpp"
|
#include "../Surface.hpp"
|
||||||
|
#include "../PerimeterGenerator.hpp"
|
||||||
|
|
||||||
#include "FillBase.hpp"
|
#include "FillBase.hpp"
|
||||||
#include "FillRectilinear.hpp"
|
#include "FillRectilinear.hpp"
|
||||||
#include "FillLightning.hpp"
|
#include "FillLightning.hpp"
|
||||||
|
#include "FillConcentric.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
@ -332,6 +334,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||||||
std::vector<SurfaceFill> surface_fills = group_fills(*this);
|
std::vector<SurfaceFill> surface_fills = group_fills(*this);
|
||||||
const Slic3r::BoundingBox bbox = this->object()->bounding_box();
|
const Slic3r::BoundingBox bbox = this->object()->bounding_box();
|
||||||
const auto resolution = this->object()->print()->config().gcode_resolution.value;
|
const auto resolution = this->object()->print()->config().gcode_resolution.value;
|
||||||
|
const auto slicing_engine = this->object()->config().slicing_engine;
|
||||||
|
|
||||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||||
{
|
{
|
||||||
@ -352,6 +355,13 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||||||
if (surface_fill.params.pattern == ipLightning)
|
if (surface_fill.params.pattern == ipLightning)
|
||||||
dynamic_cast<FillLightning::Filler*>(f.get())->generator = lightning_generator;
|
dynamic_cast<FillLightning::Filler*>(f.get())->generator = lightning_generator;
|
||||||
|
|
||||||
|
if (object()->config().slicing_engine.value == SlicingEngine::Arachne && surface_fill.params.pattern == ipConcentric) {
|
||||||
|
FillConcentric *fill_concentric = dynamic_cast<FillConcentric *>(f.get());
|
||||||
|
assert(fill_concentric != nullptr);
|
||||||
|
fill_concentric->print_config = &this->object()->print()->config();
|
||||||
|
fill_concentric->print_object_config = &this->object()->config();
|
||||||
|
}
|
||||||
|
|
||||||
// calculate flow spacing for infill pattern generation
|
// calculate flow spacing for infill pattern generation
|
||||||
bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.bridge;
|
bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.bridge;
|
||||||
double link_max_length = 0.;
|
double link_max_length = 0.;
|
||||||
@ -377,17 +387,22 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||||||
params.anchor_length = surface_fill.params.anchor_length;
|
params.anchor_length = surface_fill.params.anchor_length;
|
||||||
params.anchor_length_max = surface_fill.params.anchor_length_max;
|
params.anchor_length_max = surface_fill.params.anchor_length_max;
|
||||||
params.resolution = resolution;
|
params.resolution = resolution;
|
||||||
|
params.use_arachne = slicing_engine == SlicingEngine::Arachne && surface_fill.params.pattern == ipConcentric;
|
||||||
|
|
||||||
for (ExPolygon &expoly : surface_fill.expolygons) {
|
for (ExPolygon &expoly : surface_fill.expolygons) {
|
||||||
// Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
|
// Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
|
||||||
f->spacing = surface_fill.params.spacing;
|
f->spacing = surface_fill.params.spacing;
|
||||||
surface_fill.surface.expolygon = std::move(expoly);
|
surface_fill.surface.expolygon = std::move(expoly);
|
||||||
Polylines polylines;
|
Polylines polylines;
|
||||||
|
ThickPolylines thick_polylines;
|
||||||
try {
|
try {
|
||||||
|
if (params.use_arachne)
|
||||||
|
thick_polylines = f->fill_surface_arachne(&surface_fill.surface, params);
|
||||||
|
else
|
||||||
polylines = f->fill_surface(&surface_fill.surface, params);
|
polylines = f->fill_surface(&surface_fill.surface, params);
|
||||||
} catch (InfillFailedException &) {
|
} catch (InfillFailedException &) {
|
||||||
}
|
}
|
||||||
if (! polylines.empty()) {
|
if (!polylines.empty() || !thick_polylines.empty()) {
|
||||||
// calculate actual flow from spacing (which might have been adjusted by the infill
|
// calculate actual flow from spacing (which might have been adjusted by the infill
|
||||||
// pattern generator)
|
// pattern generator)
|
||||||
double flow_mm3_per_mm = surface_fill.params.flow.mm3_per_mm();
|
double flow_mm3_per_mm = surface_fill.params.flow.mm3_per_mm();
|
||||||
@ -406,6 +421,23 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||||||
m_regions[surface_fill.region_id]->fills.entities.push_back(eec = new ExtrusionEntityCollection());
|
m_regions[surface_fill.region_id]->fills.entities.push_back(eec = new ExtrusionEntityCollection());
|
||||||
// Only concentric fills are not sorted.
|
// Only concentric fills are not sorted.
|
||||||
eec->no_sort = f->no_sort();
|
eec->no_sort = f->no_sort();
|
||||||
|
if (params.use_arachne) {
|
||||||
|
for (const ThickPolyline &thick_polyline : thick_polylines) {
|
||||||
|
Flow new_flow = surface_fill.params.flow.with_spacing(float(f->spacing));
|
||||||
|
|
||||||
|
ExtrusionPaths paths = thick_polyline_to_extrusion_paths(thick_polyline, surface_fill.params.extrusion_role, new_flow, scaled<float>(0.05), 0);
|
||||||
|
// Append paths to collection.
|
||||||
|
if (!paths.empty()) {
|
||||||
|
if (paths.front().first_point() == paths.back().last_point())
|
||||||
|
eec->entities.emplace_back(new ExtrusionLoop(std::move(paths)));
|
||||||
|
else
|
||||||
|
for (ExtrusionPath &path : paths)
|
||||||
|
eec->entities.emplace_back(new ExtrusionPath(std::move(path)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thick_polylines.clear();
|
||||||
|
} else {
|
||||||
extrusion_entities_append_paths(
|
extrusion_entities_append_paths(
|
||||||
eec->entities, std::move(polylines),
|
eec->entities, std::move(polylines),
|
||||||
surface_fill.params.extrusion_role,
|
surface_fill.params.extrusion_role,
|
||||||
@ -413,6 +445,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add thin fill regions
|
// add thin fill regions
|
||||||
// Unpacks the collection, creates multiple collections per path.
|
// Unpacks the collection, creates multiple collections per path.
|
||||||
@ -618,6 +651,7 @@ void Layer::make_ironing()
|
|||||||
surface_fill.expolygon = std::move(expoly);
|
surface_fill.expolygon = std::move(expoly);
|
||||||
Polylines polylines;
|
Polylines polylines;
|
||||||
try {
|
try {
|
||||||
|
assert(!fill_params.use_arachne);
|
||||||
polylines = fill.fill_surface(&surface_fill, fill_params);
|
polylines = fill.fill_surface(&surface_fill, fill_params);
|
||||||
} catch (InfillFailedException &) {
|
} catch (InfillFailedException &) {
|
||||||
}
|
}
|
||||||
|
@ -82,16 +82,22 @@ Polylines Fill::fill_surface(const Surface *surface, const FillParams ¶ms)
|
|||||||
Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(this->overlap - 0.5 * this->spacing)));
|
Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(this->overlap - 0.5 * this->spacing)));
|
||||||
// Create the infills for each of the regions.
|
// Create the infills for each of the regions.
|
||||||
Polylines polylines_out;
|
Polylines polylines_out;
|
||||||
for (size_t i = 0; i < expp.size(); ++ i)
|
for (ExPolygon &expoly : expp)
|
||||||
_fill_surface_single(
|
_fill_surface_single(params, surface->thickness_layers, _infill_direction(surface), std::move(expoly), polylines_out);
|
||||||
params,
|
|
||||||
surface->thickness_layers,
|
|
||||||
_infill_direction(surface),
|
|
||||||
std::move(expp[i]),
|
|
||||||
polylines_out);
|
|
||||||
return polylines_out;
|
return polylines_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThickPolylines Fill::fill_surface_arachne(const Surface *surface, const FillParams ¶ms)
|
||||||
|
{
|
||||||
|
// Perform offset.
|
||||||
|
Slic3r::ExPolygons expp = offset_ex(surface->expolygon, float(scale_(this->overlap - 0.5 * this->spacing)));
|
||||||
|
// Create the infills for each of the regions.
|
||||||
|
ThickPolylines thick_polylines_out;
|
||||||
|
for (ExPolygon &expoly : expp)
|
||||||
|
_fill_surface_single(params, surface->thickness_layers, _infill_direction(surface), std::move(expoly), thick_polylines_out);
|
||||||
|
return thick_polylines_out;
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate a new spacing to fill width with possibly integer number of lines,
|
// Calculate a new spacing to fill width with possibly integer number of lines,
|
||||||
// the first and last line being centered at the interval ends.
|
// the first and last line being centered at the interval ends.
|
||||||
// This function possibly increases the spacing, never decreases,
|
// This function possibly increases the spacing, never decreases,
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "../Exception.hpp"
|
#include "../Exception.hpp"
|
||||||
#include "../Utils.hpp"
|
#include "../Utils.hpp"
|
||||||
#include "../ExPolygon.hpp"
|
#include "../ExPolygon.hpp"
|
||||||
|
#include "../PrintConfig.hpp"
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
@ -57,6 +58,9 @@ struct FillParams
|
|||||||
// we were requested to complete each loop;
|
// we were requested to complete each loop;
|
||||||
// in this case we don't try to make more continuous paths
|
// in this case we don't try to make more continuous paths
|
||||||
bool complete { false };
|
bool complete { false };
|
||||||
|
|
||||||
|
// For Concentric infill, to switch between Classic and Arachne.
|
||||||
|
bool use_arachne { false };
|
||||||
};
|
};
|
||||||
static_assert(IsTriviallyCopyable<FillParams>::value, "FillParams class is not POD (and it should be - see constructor).");
|
static_assert(IsTriviallyCopyable<FillParams>::value, "FillParams class is not POD (and it should be - see constructor).");
|
||||||
|
|
||||||
@ -103,6 +107,7 @@ public:
|
|||||||
|
|
||||||
// Perform the fill.
|
// Perform the fill.
|
||||||
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
||||||
|
virtual ThickPolylines fill_surface_arachne(const Surface *surface, const FillParams ¶ms);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Fill() :
|
Fill() :
|
||||||
@ -127,6 +132,13 @@ protected:
|
|||||||
ExPolygon /* expolygon */,
|
ExPolygon /* expolygon */,
|
||||||
Polylines & /* polylines_out */) {};
|
Polylines & /* polylines_out */) {};
|
||||||
|
|
||||||
|
// Used for concentric infill to generate ThickPolylines using Arachne.
|
||||||
|
virtual void _fill_surface_single(const FillParams ¶ms,
|
||||||
|
unsigned int thickness_layers,
|
||||||
|
const std::pair<float, Point> &direction,
|
||||||
|
ExPolygon expolygon,
|
||||||
|
ThickPolylines &thick_polylines_out) {}
|
||||||
|
|
||||||
virtual float _layer_angle(size_t idx) const { return (idx & 1) ? float(M_PI/2.) : 0; }
|
virtual float _layer_angle(size_t idx) const { return (idx & 1) ? float(M_PI/2.) : 0; }
|
||||||
|
|
||||||
virtual std::pair<float, Point> _infill_direction(const Surface *surface) const;
|
virtual std::pair<float, Point> _infill_direction(const Surface *surface) const;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "../ClipperUtils.hpp"
|
#include "../ClipperUtils.hpp"
|
||||||
#include "../ExPolygon.hpp"
|
#include "../ExPolygon.hpp"
|
||||||
#include "../Surface.hpp"
|
#include "../Surface.hpp"
|
||||||
|
#include "Arachne/WallToolPaths.hpp"
|
||||||
|
|
||||||
#include "FillConcentric.hpp"
|
#include "FillConcentric.hpp"
|
||||||
|
|
||||||
@ -16,11 +17,11 @@ void FillConcentric::_fill_surface_single(
|
|||||||
// no rotation is supported for this infill pattern
|
// no rotation is supported for this infill pattern
|
||||||
BoundingBox bounding_box = expolygon.contour.bounding_box();
|
BoundingBox bounding_box = expolygon.contour.bounding_box();
|
||||||
|
|
||||||
coord_t min_spacing = scale_(this->spacing);
|
coord_t min_spacing = scaled<coord_t>(this->spacing);
|
||||||
coord_t distance = coord_t(min_spacing / params.density);
|
coord_t distance = coord_t(min_spacing / params.density);
|
||||||
|
|
||||||
if (params.density > 0.9999f && !params.dont_adjust) {
|
if (params.density > 0.9999f && !params.dont_adjust) {
|
||||||
distance = this->_adjust_solid_spacing(bounding_box.size()(0), distance);
|
distance = Slic3r::FillConcentric::_adjust_solid_spacing(bounding_box.size()(0), distance);
|
||||||
this->spacing = unscale<double>(distance);
|
this->spacing = unscale<double>(distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,10 +56,76 @@ void FillConcentric::_fill_surface_single(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (j < polylines_out.size())
|
if (j < polylines_out.size())
|
||||||
polylines_out.erase(polylines_out.begin() + j, polylines_out.end());
|
polylines_out.erase(polylines_out.begin() + int(j), polylines_out.end());
|
||||||
//TODO: return ExtrusionLoop objects to get better chained paths,
|
//TODO: return ExtrusionLoop objects to get better chained paths,
|
||||||
// otherwise the outermost loop starts at the closest point to (0, 0).
|
// otherwise the outermost loop starts at the closest point to (0, 0).
|
||||||
// We want the loops to be split inside the G-code generator to get optimum path planning.
|
// We want the loops to be split inside the G-code generator to get optimum path planning.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FillConcentric::_fill_surface_single(const FillParams ¶ms,
|
||||||
|
unsigned int thickness_layers,
|
||||||
|
const std::pair<float, Point> &direction,
|
||||||
|
ExPolygon expolygon,
|
||||||
|
ThickPolylines &thick_polylines_out)
|
||||||
|
{
|
||||||
|
assert(params.use_arachne);
|
||||||
|
assert(this->print_config != nullptr && this->print_object_config != nullptr);
|
||||||
|
|
||||||
|
// no rotation is supported for this infill pattern
|
||||||
|
Point bbox_size = expolygon.contour.bounding_box().size();
|
||||||
|
coord_t min_spacing = scaled<coord_t>(this->spacing);
|
||||||
|
|
||||||
|
if (params.density > 0.9999f && !params.dont_adjust) {
|
||||||
|
coord_t loops_count = std::max(bbox_size.x(), bbox_size.y()) / min_spacing + 1;
|
||||||
|
Polygons polygons = offset(expolygon, min_spacing / 2);
|
||||||
|
Arachne::WallToolPaths wallToolPaths(polygons, min_spacing, min_spacing, loops_count, 0, *this->print_object_config, *this->print_config);
|
||||||
|
|
||||||
|
std::vector<Arachne::VariableWidthLines> loops = wallToolPaths.getToolPaths();
|
||||||
|
std::vector<const Arachne::ExtrusionLine *> all_extrusions;
|
||||||
|
for (Arachne::VariableWidthLines &loop : loops) {
|
||||||
|
if (loop.empty())
|
||||||
|
continue;
|
||||||
|
for (const Arachne::ExtrusionLine &wall : loop)
|
||||||
|
all_extrusions.emplace_back(&wall);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split paths using a nearest neighbor search.
|
||||||
|
size_t firts_poly_idx = thick_polylines_out.size();
|
||||||
|
Point last_pos(0, 0);
|
||||||
|
for (const Arachne::ExtrusionLine *extrusion : all_extrusions) {
|
||||||
|
if (extrusion->empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ThickPolyline thick_polyline = Arachne::to_thick_polyline(*extrusion);
|
||||||
|
if (extrusion->is_closed && thick_polyline.points.front() == thick_polyline.points.back() && thick_polyline.width.front() == thick_polyline.width.back()) {
|
||||||
|
thick_polyline.points.pop_back();
|
||||||
|
assert(thick_polyline.points.size() * 2 == thick_polyline.width.size());
|
||||||
|
int nearest_idx = last_pos.nearest_point_index(thick_polyline.points);
|
||||||
|
std::rotate(thick_polyline.points.begin(), thick_polyline.points.begin() + nearest_idx, thick_polyline.points.end());
|
||||||
|
std::rotate(thick_polyline.width.begin(), thick_polyline.width.begin() + 2 * nearest_idx, thick_polyline.width.end());
|
||||||
|
thick_polyline.points.emplace_back(thick_polyline.points.front());
|
||||||
|
}
|
||||||
|
thick_polylines_out.emplace_back(std::move(thick_polyline));
|
||||||
|
}
|
||||||
|
|
||||||
|
// clip the paths to prevent the extruder from getting exactly on the first point of the loop
|
||||||
|
// Keep valid paths only.
|
||||||
|
size_t j = firts_poly_idx;
|
||||||
|
for (size_t i = firts_poly_idx; i < thick_polylines_out.size(); ++i) {
|
||||||
|
thick_polylines_out[i].clip_end(this->loop_clipping);
|
||||||
|
if (thick_polylines_out[i].is_valid()) {
|
||||||
|
if (j < i)
|
||||||
|
thick_polylines_out[j] = std::move(thick_polylines_out[i]);
|
||||||
|
++j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (j < thick_polylines_out.size())
|
||||||
|
thick_polylines_out.erase(thick_polylines_out.begin() + int(j), thick_polylines_out.end());
|
||||||
|
} else {
|
||||||
|
Polylines polylines;
|
||||||
|
this->_fill_surface_single(params, thickness_layers, direction, expolygon, polylines);
|
||||||
|
append(thick_polylines_out, to_thick_polylines(std::move(polylines), min_spacing));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -19,7 +19,18 @@ protected:
|
|||||||
ExPolygon expolygon,
|
ExPolygon expolygon,
|
||||||
Polylines &polylines_out) override;
|
Polylines &polylines_out) override;
|
||||||
|
|
||||||
|
void _fill_surface_single(const FillParams ¶ms,
|
||||||
|
unsigned int thickness_layers,
|
||||||
|
const std::pair<float, Point> &direction,
|
||||||
|
ExPolygon expolygon,
|
||||||
|
ThickPolylines &thick_polylines_out) override;
|
||||||
|
|
||||||
bool no_sort() const override { return true; }
|
bool no_sort() const override { return true; }
|
||||||
|
|
||||||
|
const PrintConfig *print_config = nullptr;
|
||||||
|
const PrintObjectConfig *print_object_config = nullptr;
|
||||||
|
|
||||||
|
friend class Layer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
|
|
||||||
static ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance, const float merge_tolerance)
|
ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance, const float merge_tolerance)
|
||||||
{
|
{
|
||||||
ExtrusionPaths paths;
|
ExtrusionPaths paths;
|
||||||
ExtrusionPath path(role);
|
ExtrusionPath path(role);
|
||||||
@ -24,7 +24,7 @@ static ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thi
|
|||||||
|
|
||||||
double thickness_delta = fabs(line.a_width - line.b_width);
|
double thickness_delta = fabs(line.a_width - line.b_width);
|
||||||
if (thickness_delta > tolerance) {
|
if (thickness_delta > tolerance) {
|
||||||
const unsigned int segments = (unsigned int)ceil(thickness_delta / tolerance);
|
const auto segments = (unsigned int)ceil(thickness_delta / tolerance);
|
||||||
const coordf_t seg_len = line_len / segments;
|
const coordf_t seg_len = line_len / segments;
|
||||||
Points pp;
|
Points pp;
|
||||||
std::vector<coordf_t> width;
|
std::vector<coordf_t> width;
|
||||||
|
@ -72,6 +72,8 @@ private:
|
|||||||
Polygons m_lower_slices_polygons;
|
Polygons m_lower_slices_polygons;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance, const float merge_tolerance);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -235,6 +235,34 @@ ThickLines ThickPolyline::thicklines() const
|
|||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Removes the given distance from the end of the ThickPolyline
|
||||||
|
void ThickPolyline::clip_end(double distance)
|
||||||
|
{
|
||||||
|
while (distance > 0) {
|
||||||
|
Vec2d last_point = this->last_point().cast<double>();
|
||||||
|
coordf_t last_width = this->width.back();
|
||||||
|
this->points.pop_back();
|
||||||
|
this->width.pop_back();
|
||||||
|
if (this->points.empty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
Vec2d vec = this->last_point().cast<double>() - last_point;
|
||||||
|
coordf_t width_diff = this->width.back() - last_width;
|
||||||
|
double vec_length_sqr = vec.squaredNorm();
|
||||||
|
if (vec_length_sqr > distance * distance) {
|
||||||
|
double t = (distance / std::sqrt(vec_length_sqr));
|
||||||
|
this->points.emplace_back((last_point + vec * t).cast<coord_t>());
|
||||||
|
this->width.emplace_back(last_width + width_diff * t);
|
||||||
|
assert(this->width.size() == (this->points.size() - 1) * 2);
|
||||||
|
return;
|
||||||
|
} else
|
||||||
|
this->width.pop_back();
|
||||||
|
|
||||||
|
distance -= std::sqrt(vec_length_sqr);
|
||||||
|
}
|
||||||
|
assert(this->width.size() == (this->points.size() - 1) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
Lines3 Polyline3::lines() const
|
Lines3 Polyline3::lines() const
|
||||||
{
|
{
|
||||||
Lines3 lines;
|
Lines3 lines;
|
||||||
|
@ -64,7 +64,7 @@ public:
|
|||||||
const Point& leftmost_point() const;
|
const Point& leftmost_point() const;
|
||||||
Lines lines() const override;
|
Lines lines() const override;
|
||||||
|
|
||||||
void clip_end(double distance);
|
virtual void clip_end(double distance);
|
||||||
void clip_start(double distance);
|
void clip_start(double distance);
|
||||||
void extend_end(double distance);
|
void extend_end(double distance);
|
||||||
void extend_start(double distance);
|
void extend_start(double distance);
|
||||||
@ -172,10 +172,24 @@ public:
|
|||||||
std::swap(this->endpoints.first, this->endpoints.second);
|
std::swap(this->endpoints.first, this->endpoints.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clip_end(double distance) override;
|
||||||
|
|
||||||
std::vector<coordf_t> width;
|
std::vector<coordf_t> width;
|
||||||
std::pair<bool,bool> endpoints;
|
std::pair<bool,bool> endpoints;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline ThickPolylines to_thick_polylines(Polylines &&polylines, const coordf_t width)
|
||||||
|
{
|
||||||
|
ThickPolylines out;
|
||||||
|
out.reserve(polylines.size());
|
||||||
|
for (Polyline &polyline : polylines) {
|
||||||
|
out.emplace_back();
|
||||||
|
out.back().width.assign((polyline.points.size() - 1) * 2, width);
|
||||||
|
out.back().points = std::move(polyline.points);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
class Polyline3 : public MultiPoint3
|
class Polyline3 : public MultiPoint3
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -3243,6 +3243,7 @@ static inline void fill_expolygon_generate_paths(
|
|||||||
Surface surface(stInternal, std::move(expolygon));
|
Surface surface(stInternal, std::move(expolygon));
|
||||||
Polylines polylines;
|
Polylines polylines;
|
||||||
try {
|
try {
|
||||||
|
assert(!fill_params.use_arachne);
|
||||||
polylines = filler->fill_surface(&surface, fill_params);
|
polylines = filler->fill_surface(&surface, fill_params);
|
||||||
} catch (InfillFailedException &) {
|
} catch (InfillFailedException &) {
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ TEST_CASE("Fill: Pattern Path Length", "[Fill]") {
|
|||||||
FillParams fill_params;
|
FillParams fill_params;
|
||||||
fill_params.density = 1.0;
|
fill_params.density = 1.0;
|
||||||
filler->spacing = flow.spacing();
|
filler->spacing = flow.spacing();
|
||||||
|
REQUIRE(!fill_params.use_arachne); // Make this test fail when Arachne is used because this test is not ready for it.
|
||||||
for (auto angle : { 0.0, 45.0}) {
|
for (auto angle : { 0.0, 45.0}) {
|
||||||
surface.expolygon.rotate(angle, Point(0,0));
|
surface.expolygon.rotate(angle, Point(0,0));
|
||||||
Polylines paths = filler->fill_surface(&surface, fill_params);
|
Polylines paths = filler->fill_surface(&surface, fill_params);
|
||||||
@ -443,6 +443,8 @@ bool test_if_solid_surface_filled(const ExPolygon& expolygon, double flow_spacin
|
|||||||
fill_params.dont_adjust = false;
|
fill_params.dont_adjust = false;
|
||||||
|
|
||||||
Surface surface(stBottom, expolygon);
|
Surface surface(stBottom, expolygon);
|
||||||
|
if (fill_params.use_arachne) // Make this test fail when Arachne is used because this test is not ready for it.
|
||||||
|
return false;
|
||||||
Slic3r::Polylines paths = filler->fill_surface(&surface, fill_params);
|
Slic3r::Polylines paths = filler->fill_surface(&surface, fill_params);
|
||||||
|
|
||||||
// check whether any part was left uncovered
|
// check whether any part was left uncovered
|
||||||
|
Loading…
Reference in New Issue
Block a user