Fix an "External Perimeter First" that extrude each perimeter in double if only one of the two selected.

supermerill/SuperSlicer#2267
This commit is contained in:
remi durand 2022-01-26 16:28:59 +01:00 committed by supermerill
parent ec2d3e96e7
commit 2df72fd324
21 changed files with 253 additions and 249 deletions

View File

@ -55,9 +55,11 @@ double ExtrusionPath::length() const
void ExtrusionPath::_inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const
{
ExtrusionEntitiesPtr to_add;
for (const Polyline &polyline : polylines)
collection->entities.emplace_back(new ExtrusionPath(polyline, *this));
}
to_add.emplace_back(new ExtrusionPath(polyline, *this));
collection->append(std::move(to_add));
}
void ExtrusionPath::polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const
{
@ -376,9 +378,9 @@ void ExtrusionPrinter::use(const ExtrusionLoop &loop) {
}
void ExtrusionPrinter::use(const ExtrusionEntityCollection &collection) {
ss << "ExtrusionEntityCollection:" << (uint16_t)collection.role() << "{";
for (int i = 0; i < collection.entities.size(); i++) {
for (int i = 0; i < collection.entities().size(); i++) {
if (i != 0) ss << ",";
collection.entities[i]->visit(*this);
collection.entities()[i]->visit(*this);
}
if(!collection.can_sort()) ss<<", no_sort=true";
ss << "}";
@ -387,8 +389,8 @@ void ExtrusionPrinter::use(const ExtrusionEntityCollection &collection) {
void ExtrusionLength::default_use(const ExtrusionEntity& entity) { dist += entity.length(); };
void ExtrusionLength::use(const ExtrusionEntityCollection& collection) {
for (int i = 0; i < collection.entities.size(); i++) {
collection.entities[i]->visit(*this);
for (int i = 0; i < collection.entities().size(); i++) {
collection.entities()[i]->visit(*this);
}
}
@ -409,7 +411,7 @@ void ExtrusionVisitorRecursiveConst::use(const ExtrusionLoop& loop) {
}
}
void ExtrusionVisitorRecursiveConst::use(const ExtrusionEntityCollection& collection) {
for (const ExtrusionEntity* entity : collection.entities) {
for (const ExtrusionEntity* entity : collection.entities()) {
entity->visit(*this);
}
}

View File

@ -28,27 +28,27 @@ ExtrusionEntityCollection& ExtrusionEntityCollection::operator= (const Extrusion
{
this->no_sort = other.no_sort;
clear();
this->append(other.entities);
this->append(other.m_entities);
return *this;
}
void ExtrusionEntityCollection::swap(ExtrusionEntityCollection &c)
{
std::swap(this->entities, c.entities);
std::swap(this->m_entities, c.m_entities);
std::swap(this->no_sort, c.no_sort);
}
void ExtrusionEntityCollection::clear()
{
for (size_t i = 0; i < this->entities.size(); ++i)
delete this->entities[i];
this->entities.clear();
for (size_t i = 0; i < this->m_entities.size(); ++i)
delete this->m_entities[i];
this->m_entities.clear();
}
ExtrusionEntityCollection::operator ExtrusionPaths() const
{
ExtrusionPaths paths;
for (const ExtrusionEntity *ptr : this->entities) {
for (const ExtrusionEntity *ptr : this->entities()) {
if (const ExtrusionPath *path = dynamic_cast<const ExtrusionPath*>(ptr))
paths.push_back(*path);
}
@ -57,26 +57,26 @@ ExtrusionEntityCollection::operator ExtrusionPaths() const
void ExtrusionEntityCollection::reverse()
{
for (ExtrusionEntity *ptr : this->entities)
for (ExtrusionEntity *ptr : this->m_entities)
{
// Don't reverse it if it's a loop, as it doesn't change anything in terms of elements ordering
// and caller might rely on winding order
if (ptr->can_reverse() && !ptr->is_loop())
ptr->reverse();
}
std::reverse(this->entities.begin(), this->entities.end());
std::reverse(this->m_entities.begin(), this->m_entities.end());
}
void ExtrusionEntityCollection::replace(size_t i, const ExtrusionEntity &entity)
{
delete this->entities[i];
this->entities[i] = entity.clone();
delete this->m_entities[i];
this->m_entities[i] = entity.clone();
}
void ExtrusionEntityCollection::remove(size_t i)
{
delete this->entities[i];
this->entities.erase(this->entities.begin() + i);
delete this->m_entities[i];
this->m_entities.erase(this->m_entities.begin() + i);
}
ExtrusionEntityCollection ExtrusionEntityCollection::chained_path_from(const ExtrusionEntitiesPtr& extrusion_entities, const Point &start_near, ExtrusionRole role)
@ -89,7 +89,7 @@ ExtrusionEntityCollection ExtrusionEntityCollection::chained_path_from(const Ext
// if (role == erMixed)
// out = *this;
// else {
// for (const ExtrusionEntity *ee : this->entities) {
// for (const ExtrusionEntity *ee : this->entities()) {
// if (role != erMixed) {
// // The caller wants only paths with a specific extrusion role.
// auto role2 = ee->role();
@ -99,31 +99,31 @@ ExtrusionEntityCollection ExtrusionEntityCollection::chained_path_from(const Ext
// continue;
// }
// }
// out.entities.emplace_back(ee->clone());
// out.entities().emplace_back(ee->clone());
// }
// }
// chain_and_reorder_extrusion_entities(out.entities, &start_near);
// chain_and_reorder_extrusion_entities(out.entities(), &start_near);
//}
//return out;
// Return a filtered copy of the collection.
ExtrusionEntityCollection out;
out.entities = filter_by_extrusion_role(extrusion_entities, role);
out.m_entities = filter_by_extrusion_role(extrusion_entities, role);
// Clone the extrusion entities.
for (ExtrusionEntity* &ptr : out.entities)
for (ExtrusionEntity* &ptr : out.m_entities)
ptr = ptr->clone();
chain_and_reorder_extrusion_entities(out.entities, &start_near);
chain_and_reorder_extrusion_entities(out.m_entities, &start_near);
return out;
}
void ExtrusionEntityCollection::polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const
{
for (const ExtrusionEntity *entity : this->entities)
for (const ExtrusionEntity *entity : this->entities())
entity->polygons_covered_by_width(out, scaled_epsilon);
}
void ExtrusionEntityCollection::polygons_covered_by_spacing(Polygons &out, const float spacing_ratio, const float scaled_epsilon) const
{
for (const ExtrusionEntity *entity : this->entities)
for (const ExtrusionEntity *entity : this->entities())
entity->polygons_covered_by_spacing(out, spacing_ratio, scaled_epsilon);
}
@ -135,7 +135,7 @@ size_t ExtrusionEntityCollection::items_count() const
void
CountEntities::use(const ExtrusionEntityCollection &coll) {
for (const ExtrusionEntity* entity : coll.entities) {
for (const ExtrusionEntity* entity : coll.entities()) {
entity->visit(*this);
}
}
@ -153,12 +153,12 @@ void
FlatenEntities::use(const ExtrusionEntityCollection &coll) {
if ((!coll.can_sort() || !this->to_fill.can_sort()) && preserve_ordering) {
FlatenEntities unsortable(coll, preserve_ordering);
for (const ExtrusionEntity* entity : coll.entities) {
for (const ExtrusionEntity* entity : coll.entities()) {
entity->visit(unsortable);
}
to_fill.append(std::move(unsortable.to_fill));
} else {
for (const ExtrusionEntity* entity : coll.entities) {
for (const ExtrusionEntity* entity : coll.entities()) {
entity->visit(*this);
}
}

View File

@ -29,6 +29,7 @@ private:
bool no_sort;
// even if no_sort, allow to reverse() us (and our entities if they allow it, but they should)
bool no_reverse;
ExtrusionEntitiesPtr m_entities; // we own these entities
public:
virtual ExtrusionEntityCollection* clone() const override { return new ExtrusionEntityCollection(*this); }
// Create a new object, initialize it with this object using the move semantics.
@ -37,14 +38,15 @@ public:
/// Owned ExtrusionEntities and descendent ExtrusionEntityCollections.
/// Iterating over this needs to check each child to see if it, too is a collection.
ExtrusionEntitiesPtr entities; // we own these entities
const ExtrusionEntitiesPtr& entities() const { return m_entities; }
ExtrusionEntitiesPtr& set_entities() { return m_entities; }
ExtrusionEntityCollection(): no_sort(false), no_reverse(false) {}
ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : no_sort(other.no_sort), no_reverse(other.no_reverse) { this->append(other.entities); }
ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : entities(std::move(other.entities)), no_sort(other.no_sort), no_reverse(other.no_reverse) {}
ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : no_sort(other.no_sort), no_reverse(other.no_reverse) { this->append(other.entities()); }
ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : m_entities(std::move(other.m_entities)), no_sort(other.no_sort), no_reverse(other.no_reverse) {}
explicit ExtrusionEntityCollection(const ExtrusionPaths &paths);
ExtrusionEntityCollection& operator=(const ExtrusionEntityCollection &other);
ExtrusionEntityCollection& operator=(ExtrusionEntityCollection &&other)
{ this->entities = std::move(other.entities); this->no_sort = other.no_sort; this->no_reverse = other.no_reverse; return *this; }
{ this->m_entities = std::move(other.m_entities); this->no_sort = other.no_sort; this->no_reverse = other.no_reverse; return *this; }
~ExtrusionEntityCollection() { clear(); }
/// Operator to convert and flatten this collection to a single vector of ExtrusionPaths.
@ -53,7 +55,7 @@ public:
bool is_collection() const override { return true; }
ExtrusionRole role() const override {
ExtrusionRole out = erNone;
for (const ExtrusionEntity *ee : entities) {
for (const ExtrusionEntity *ee : m_entities) {
ExtrusionRole er = ee->role();
out = (out == erNone || out == er) ? er : erMixed;
}
@ -62,33 +64,33 @@ public:
void set_can_sort_reverse(bool sort, bool reverse) { this->no_sort = !sort; this->no_reverse = !reverse; }
bool can_sort() const { return !this->no_sort; }
bool can_reverse() const override { return can_sort() || !this->no_reverse; }
bool empty() const { return this->entities.empty(); }
bool empty() const { return this->m_entities.empty(); }
void clear();
void swap (ExtrusionEntityCollection &c);
void append(const ExtrusionEntity &entity) { this->entities.emplace_back(entity.clone()); }
void append(ExtrusionEntity &&entity) { this->entities.emplace_back(entity.clone_move()); }
void append(const ExtrusionEntity &entity) { this->m_entities.emplace_back(entity.clone()); }
void append(ExtrusionEntity &&entity) { this->m_entities.emplace_back(entity.clone_move()); }
void append(const ExtrusionEntitiesPtr &entities) {
this->entities.reserve(this->entities.size() + entities.size());
this->m_entities.reserve(this->m_entities.size() + entities.size());
for (const ExtrusionEntity *ptr : entities)
this->entities.emplace_back(ptr->clone());
this->m_entities.emplace_back(ptr->clone());
}
void append(ExtrusionEntitiesPtr &&src) {
if (entities.empty())
entities = std::move(src);
if (m_entities.empty())
m_entities = std::move(src);
else {
std::move(std::begin(src), std::end(src), std::back_inserter(entities));
std::move(std::begin(src), std::end(src), std::back_inserter(m_entities));
src.clear();
}
}
void append(const ExtrusionPaths &paths) {
this->entities.reserve(this->entities.size() + paths.size());
this->m_entities.reserve(this->m_entities.size() + paths.size());
for (const ExtrusionPath &path : paths)
this->entities.emplace_back(path.clone());
this->m_entities.emplace_back(path.clone());
}
void append(ExtrusionPaths &&paths) {
this->entities.reserve(this->entities.size() + paths.size());
this->m_entities.reserve(this->m_entities.size() + paths.size());
for (ExtrusionPath &path : paths)
this->entities.emplace_back(new ExtrusionPath(std::move(path)));
this->m_entities.emplace_back(new ExtrusionPath(std::move(path)));
}
void replace(size_t i, const ExtrusionEntity &entity);
void remove(size_t i);
@ -98,11 +100,11 @@ public:
if( this->no_sort || (role == erMixed) )
return *this;
else
return chained_path_from(this->entities, start_near, role);
return chained_path_from(this->m_entities, start_near, role);
}
void reverse() override;
const Point& first_point() const override { return this->entities.front()->first_point(); }
const Point& last_point() const override { return this->entities.back()->last_point(); }
const Point& first_point() const override { return this->entities().front()->first_point(); }
const Point& last_point() const override { return this->entities().back()->last_point(); }
// Produce a list of 2D polygons covered by the extruded paths, offsetted by the extrusion width.
// Increase the offset by scaled_epsilon to achieve an overlap, so a union will produce no gaps.
void polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const override;
@ -117,11 +119,11 @@ public:
/// Recursively count paths and loops contained in this collection
size_t items_count() const;
/// Returns a flattened copy of this ExtrusionEntityCollection. That is, all of the items in its entities vector are not collections.
/// You should be iterating over flatten().entities if you are interested in the underlying ExtrusionEntities (and don't care about hierarchy).
/// Returns a flattened copy of this ExtrusionEntityCollection. That is, all of the items in its entities() vector are not collections.
/// You should be iterating over flatten().entities() if you are interested in the underlying ExtrusionEntities (and don't care about hierarchy).
/// \param preserve_ordering Flag to method that will flatten if and only if the underlying collection is sortable when True (default: False).
ExtrusionEntityCollection flatten(bool preserve_ordering = false) const;
double total_volume() const override { double volume=0.; for (const auto& ent : entities) volume+=ent->total_volume(); return volume; }
double total_volume() const override { double volume=0.; for (const auto& ent : entities()) volume+=ent->total_volume(); return volume; }
// Following methods shall never be called on an ExtrusionEntityCollection.
Polyline as_polyline() const override {
@ -130,7 +132,7 @@ public:
};
void collect_polylines(Polylines &dst) const override {
for (ExtrusionEntity* extrusion_entity : this->entities)
for (const ExtrusionEntity* extrusion_entity : this->entities())
extrusion_entity->collect_polylines(dst);
}

View File

@ -410,19 +410,19 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
std::vector<ExtrusionEntityCollection*> fills_by_priority;
auto store_fill = [&fills_by_priority, this](size_t region_id) {
if (fills_by_priority.size() == 1) {
m_regions[region_id]->fills.append(fills_by_priority[0]->entities);
m_regions[region_id]->fills.append(fills_by_priority[0]->entities());
delete fills_by_priority[0];
} else {
m_regions[region_id]->fills.set_can_sort_reverse(false, false);
ExtrusionEntityCollection* eec = new ExtrusionEntityCollection();
eec->set_can_sort_reverse(false, false);
m_regions[region_id]->fills.entities.push_back(eec);
for (ExtrusionEntityCollection* per_priority : fills_by_priority) {
if (!per_priority->entities.empty())
eec->entities.push_back(per_priority);
if (!per_priority->entities().empty())
eec->set_entities().push_back(per_priority);
else
delete per_priority;
}
m_regions[region_id]->fills.append(ExtrusionEntitiesPtr{ eec });
}
fills_by_priority.clear();
};
@ -568,7 +568,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
//make fill
while ((size_t)surface_fill.params.priority >= fills_by_priority.size())
fills_by_priority.push_back(new ExtrusionEntityCollection());
f->fill_surface_extrusion(&surface_fill.surface, surface_fill.params, fills_by_priority[(size_t)surface_fill.params.priority]->entities);
f->fill_surface_extrusion(&surface_fill.surface, surface_fill.params, fills_by_priority[(size_t)surface_fill.params.priority]->set_entities());
}
}
}
@ -580,32 +580,32 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
// The path type could be ExtrusionPath, ExtrusionLoop or ExtrusionEntityCollection.
// Why the paths are unpacked?
for (LayerRegion *layerm : m_regions)
for (const ExtrusionEntity *thin_fill : layerm->thin_fills.entities) {
for (const ExtrusionEntity *thin_fill : layerm->thin_fills.entities()) {
ExtrusionEntityCollection *collection = new ExtrusionEntityCollection();
if (!layerm->fills.can_sort() && layerm->fills.entities.size() > 0 && layerm->fills.entities[0]->is_collection()) {
ExtrusionEntityCollection* no_sort_fill = static_cast<ExtrusionEntityCollection*>(layerm->fills.entities[0]);
if (!no_sort_fill->can_sort() && no_sort_fill->entities.size() > 0 && no_sort_fill->entities[0]->is_collection())
static_cast<ExtrusionEntityCollection*>(no_sort_fill->entities[0])->entities.push_back(collection);
if (!layerm->fills.can_sort() && layerm->fills.entities().size() > 0 && layerm->fills.entities()[0]->is_collection()) {
ExtrusionEntityCollection* no_sort_fill = static_cast<ExtrusionEntityCollection*>(layerm->fills.entities()[0]);
if (!no_sort_fill->can_sort() && no_sort_fill->entities().size() > 0 && no_sort_fill->entities()[0]->is_collection())
static_cast<ExtrusionEntityCollection*>(no_sort_fill->entities()[0])->append(ExtrusionEntitiesPtr{ collection });
} else
layerm->fills.entities.push_back(collection);
collection->entities.push_back(thin_fill->clone());
layerm->fills.append(ExtrusionEntitiesPtr{ collection });
collection->append(*thin_fill);
}
#ifndef NDEBUG
for (LayerRegion *layerm : m_regions)
for (size_t i1 = 0; i1 < layerm->fills.entities.size(); ++i1) {
assert(dynamic_cast<ExtrusionEntityCollection*>(layerm->fills.entities[i1]) != nullptr);
if (!layerm->fills.can_sort() && layerm->fills.entities.size() > 0 && i1 == 0){
ExtrusionEntityCollection* no_sort_fill = static_cast<ExtrusionEntityCollection*>(layerm->fills.entities[0]);
for (size_t i1 = 0; i1 < layerm->fills.entities().size(); ++i1) {
assert(dynamic_cast<ExtrusionEntityCollection*>(layerm->fills.entities()[i1]) != nullptr);
if (!layerm->fills.can_sort() && layerm->fills.entities().size() > 0 && i1 == 0){
ExtrusionEntityCollection* no_sort_fill = static_cast<ExtrusionEntityCollection*>(layerm->fills.entities()[0]);
assert(no_sort_fill != nullptr);
assert(!no_sort_fill->empty());
for (size_t i2 = 0; i2 < no_sort_fill->entities.size(); ++i2) {
ExtrusionEntityCollection* priority_fill = dynamic_cast<ExtrusionEntityCollection*>(no_sort_fill->entities[i2]);
for (size_t i2 = 0; i2 < no_sort_fill->entities().size(); ++i2) {
ExtrusionEntityCollection* priority_fill = dynamic_cast<ExtrusionEntityCollection*>(no_sort_fill->entities()[i2]);
assert(priority_fill != nullptr);
assert(!priority_fill->empty());
if (!no_sort_fill->can_sort()) {
for (size_t i3 = 0; i3 < priority_fill->entities.size(); ++i3)
assert(dynamic_cast<ExtrusionEntityCollection*>(priority_fill->entities[i3]) != nullptr);
for (size_t i3 = 0; i3 < priority_fill->entities().size(); ++i3)
assert(dynamic_cast<ExtrusionEntityCollection*>(priority_fill->entities()[i3]) != nullptr);
}
}
}
@ -780,11 +780,11 @@ void Layer::make_ironing()
if (! polylines.empty()) {
// Save into layer.
ExtrusionEntityCollection *eec = new ExtrusionEntityCollection();
ironing_params.layerm->ironings.entities.push_back(eec);
ironing_params.layerm->ironings.append(ExtrusionEntitiesPtr{ eec });
// Don't sort the ironing infill lines as they are monotonicly ordered.
eec->set_can_sort_reverse(false, false);
extrusion_entities_append_paths(
eec->entities, std::move(polylines),
eec->set_entities(), std::move(polylines),
erIroning,
flow_mm3_per_mm, float(flow.width), float(height));
}

View File

@ -218,7 +218,7 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams &para
ExtrusionRole good_role = getRoleFromSurfaceType(params, surface);
/// push the path
extrusion_entities_append_paths(
eec->entities, std::move(polylines),
eec->set_entities(), std::move(polylines),
good_role,
params.flow.mm3_per_mm() * params.flow_mult * mult_flow,
(float)(params.flow.width * params.flow_mult * mult_flow),
@ -276,10 +276,10 @@ Fill::do_gap_fill(const ExPolygons& gapfill_areas, const FillParams& params, Ext
gap_fill.visit(set_good_role);
}*/
//move them into the collection
if (!gap_fill.entities.empty()) {
if (!gap_fill.entities().empty()) {
ExtrusionEntityCollection* coll_gapfill = new ExtrusionEntityCollection();
coll_gapfill->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
coll_gapfill->append(std::move(gap_fill.entities));
coll_gapfill->append(std::move(gap_fill.entities()));
coll_out.push_back(coll_gapfill);
}
}

View File

@ -230,7 +230,7 @@ public:
void use(ExtrusionMultiPath &multipath) override { for (ExtrusionPath path : multipath.paths) path.set_role(new_role); }
void use(ExtrusionMultiPath3D &multipath) override { for (ExtrusionPath path : multipath.paths) path.set_role(new_role); }
void use(ExtrusionLoop &loop) override { for (ExtrusionPath path : loop.paths) path.set_role(new_role); }
void use(ExtrusionEntityCollection &collection) override { for (ExtrusionEntity *entity : collection.entities) entity->visit(*this); }
void use(ExtrusionEntityCollection &collection) override { for (ExtrusionEntity *entity : collection.entities()) entity->visit(*this); }
};
} // namespace Slic3r

View File

@ -132,7 +132,7 @@ FillConcentricWGapFill::fill_surface_extrusion(
ExtrusionEntityCollection *coll_nosort = new ExtrusionEntityCollection();
coll_nosort->set_can_sort_reverse(false, false); //can be sorted inside the pass
extrusion_entities_append_loops(
coll_nosort->entities, loops,
coll_nosort->set_entities(), loops,
good_role,
params.flow.mm3_per_mm() * params.flow_mult,
params.flow.width * params.flow_mult,
@ -163,11 +163,11 @@ FillConcentricWGapFill::fill_surface_extrusion(
gap_fill.visit(set_good_role);
}
//move them into the collection
coll_nosort->append(std::move(gap_fill.entities));
coll_nosort->append(std::move(gap_fill.entities()));
}
}
if (!coll_nosort->entities.empty())
if (!coll_nosort->entities().empty())
out.push_back(coll_nosort);
else delete coll_nosort;
}

View File

@ -3233,12 +3233,12 @@ FillRectilinearPeri::fill_surface_extrusion(const Surface *surface, const FillPa
/// pass the no_sort attribute to the extrusion path
eec->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
/// add it into the collection
eecroot->entities.push_back(eec);
eecroot->append(ExtrusionEntitiesPtr{ eec });
//get the role
ExtrusionRole good_role = getRoleFromSurfaceType(params, surface);
/// push the path
extrusion_entities_append_paths(
eec->entities,
eec->set_entities(),
polylines_1,
good_role,
params.flow.mm3_per_mm() * params.flow_mult,
@ -3265,12 +3265,12 @@ FillRectilinearPeri::fill_surface_extrusion(const Surface *surface, const FillPa
/// pass the no_sort attribute to the extrusion path
eec->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
/// add it into the collection
eecroot->entities.push_back(eec);
eecroot->append(ExtrusionEntitiesPtr{ eec });
//get the role
ExtrusionRole good_role = getRoleFromSurfaceType(params, surface);
/// push the path
extrusion_entities_append_paths(
eec->entities,
eec->set_entities(),
polylines_2,
good_role,
params.flow.mm3_per_mm() * params.flow_mult,
@ -3455,7 +3455,7 @@ FillRectilinearSawtooth::fill_surface_extrusion(const Surface *surface, const Fi
idx++;
}
if (current_extrusion->size() < 2) extrusions->paths.pop_back();
if (!extrusions->paths.empty()) eec->entities.push_back(extrusions);
if (!extrusions->paths.empty()) eec->append(ExtrusionEntitiesPtr{ extrusions });
else delete extrusions;
}
// === end ===
@ -3563,13 +3563,13 @@ FillRectilinearWGapFill::fill_surface_extrusion(const Surface *surface, const Fi
eec->set_can_sort_reverse(!this->no_sort(), !this->no_sort());
extrusion_entities_append_paths(
eec->entities, polylines_rectilinear,
eec->set_entities(), polylines_rectilinear,
good_role,
params.flow.mm3_per_mm() * params.flow_mult * flow_mult_exact_volume,
params.flow.width * params.flow_mult * float(flow_mult_exact_volume),
params.flow.height);
coll_nosort->entities.push_back(eec);
coll_nosort->append(ExtrusionEntitiesPtr{ eec });
unextruded_areas = diff_ex(rectilinear_areas, union_ex(eec->polygons_covered_by_spacing(params.flow.spacing_ratio , 10), true));
}
@ -3590,7 +3590,7 @@ FillRectilinearWGapFill::fill_surface_extrusion(const Surface *surface, const Fi
FillParams params2{ params };
params2.role = good_role;
do_gap_fill(intersection_ex(gapfill_areas, no_overlap_expolygons), params2, coll_nosort->entities);
do_gap_fill(intersection_ex(gapfill_areas, no_overlap_expolygons), params2, coll_nosort->set_entities());
}
// === end ===

View File

@ -56,8 +56,8 @@ namespace Slic3r {
}
}
if (eec->entities.empty()) delete eec;
else eecroot.entities.push_back(eec);
if (eec->entities().empty()) delete eec;
else eecroot.append(ExtrusionEntitiesPtr{ eec });
}
void FillSmooth::fill_expolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill,
@ -115,7 +115,7 @@ namespace Slic3r {
}
extrusion_entities_append_paths(
eec.entities, std::move(polylines_layer),
eec.set_entities(), std::move(polylines_layer),
good_role,
params.flow.mm3_per_mm() * params.flow_mult * mult_flow,
//min-reduced flow width for a better view (it's mostly a gui thing, but some support code can want to mess with it)
@ -153,7 +153,7 @@ namespace Slic3r {
perform_single_fill(2, *eecroot, *surface, monotonic_params);
}
if (!eecroot->entities.empty())
if (!eecroot->entities().empty())
out.push_back(eecroot);
else delete eecroot;

View File

@ -820,7 +820,7 @@ namespace DoExport {
use(path);
}
virtual void use(const ExtrusionEntityCollection& collection) override {
for (const ExtrusionEntity* entity : collection.entities)
for (const ExtrusionEntity* entity : collection.entities())
entity->visit(*this);
}
double reset_use_get(const ExtrusionEntityCollection entity) { reset(); use(entity); return get(); }
@ -892,7 +892,7 @@ namespace DoExport {
// Calculate wiping points if needed
if (print.config().ooze_prevention.value && ! print.config().single_extruder_multi_material) {
Points skirt_points;
for (const ExtrusionEntity *ee : print.skirt().entities)
for (const ExtrusionEntity *ee : print.skirt().entities())
for (const ExtrusionPath &path : dynamic_cast<const ExtrusionLoop*>(ee)->paths)
append(skirt_points, path.polyline.points);
if (! skirt_points.empty()) {
@ -2131,7 +2131,7 @@ namespace Skirt {
static void skirt_loops_per_extruder_all_printing(const Print &print, const LayerTools &layer_tools, std::map<uint16_t, std::pair<size_t, size_t>> &skirt_loops_per_extruder_out)
{
// Prime all extruders printing over the 1st layer over the skirt lines.
size_t n_loops = print.skirt().entities.size();
size_t n_loops = print.skirt().entities().size();
size_t n_tools = layer_tools.extruders.size();
size_t lines_per_extruder = (n_loops + n_tools - 1) / n_tools;
for (size_t i = 0; i < n_loops; i += lines_per_extruder)
@ -2148,9 +2148,9 @@ namespace Skirt {
// Extrude skirt at the print_z of the raft layers and normal object layers
// not at the print_z of the interlaced support material layers.
std::map<uint16_t, std::pair<size_t, size_t>> skirt_loops_per_extruder_out;
if (skirt_done.empty() && print.has_skirt() && ! print.skirt().entities.empty()) {
if (skirt_done.empty() && print.has_skirt() && ! print.skirt().entities().empty()) {
if (print.skirt_first_layer()) {
size_t n_loops = print.skirt_first_layer()->entities.size();
size_t n_loops = print.skirt_first_layer()->entities().size();
size_t n_tools = layer_tools.extruders.size();
size_t lines_per_extruder = (n_loops + n_tools - 1) / n_tools;
for (size_t i = 0; i < n_loops; i += lines_per_extruder)
@ -2174,7 +2174,7 @@ namespace Skirt {
// Extrude skirt at the print_z of the raft layers and normal object layers
// not at the print_z of the interlaced support material layers.
std::map<uint16_t, std::pair<size_t, size_t>> skirt_loops_per_extruder_out;
if (print.has_skirt() && ! print.skirt().entities.empty() &&
if (print.has_skirt() && ! print.skirt().entities().empty() &&
// infinite or high skirt does not make sense for sequential print here
//(if it is selected, it's done in the "extrude object-only skirt" in process_layer)
// Not enough skirt layers printed yet.
@ -2360,7 +2360,7 @@ void GCode::process_layer(
if (layer_to_print.support_layer != nullptr) {
const SupportLayer &support_layer = *layer_to_print.support_layer;
const PrintObject &object = *support_layer.object();
if (! support_layer.support_fills.entities.empty()) {
if (! support_layer.support_fills.entities().empty()) {
ExtrusionRole role = support_layer.support_fills.role();
bool has_support = role == erMixed || role == erSupportMaterial;
bool has_interface = role == erMixed || role == erSupportMaterialInterface;
@ -2450,7 +2450,7 @@ void GCode::process_layer(
// extrusions represents infill or perimeter extrusions of a single island.
assert(dynamic_cast<const ExtrusionEntityCollection*>(ee) != nullptr);
const auto* extrusions = static_cast<const ExtrusionEntityCollection*>(ee);
if (extrusions->entities.empty()) // This shouldn't happen but first_point() would fail.
if (extrusions->entities().empty()) // This shouldn't happen but first_point() would fail.
continue;
// This extrusion is part of certain Region, which tells us which extruder should be used for it:
@ -2505,9 +2505,9 @@ void GCode::process_layer(
}
}
};
process_entities(ObjectByExtruder::Island::Region::INFILL, layerm->fills.entities);
process_entities(ObjectByExtruder::Island::Region::PERIMETERS, layerm->perimeters.entities);
process_entities(ObjectByExtruder::Island::Region::IRONING, layerm->ironings.entities);
process_entities(ObjectByExtruder::Island::Region::INFILL, layerm->fills.entities());
process_entities(ObjectByExtruder::Island::Region::PERIMETERS, layerm->perimeters.entities());
process_entities(ObjectByExtruder::Island::Region::IRONING, layerm->ironings.entities());
} // for regions
}
} // for objects
@ -2540,7 +2540,7 @@ void GCode::process_layer(
const ExtrusionEntityCollection& coll = first_layer && print.skirt_first_layer() ? *print.skirt_first_layer() : print.skirt();
for (size_t i = loops.first; i < loops.second; ++i) {
// Adjust flow according to this layer's layer height.
ExtrusionLoop loop = *dynamic_cast<const ExtrusionLoop*>(coll.entities[i]);
ExtrusionLoop loop = *dynamic_cast<const ExtrusionLoop*>(coll.entities()[i]);
for (ExtrusionPath &path : loop.paths) {
assert(layer_skirt_flow.height == layer_skirt_flow.height);
assert(mm3_per_mm == mm3_per_mm);
@ -2562,7 +2562,7 @@ void GCode::process_layer(
if (! m_brim_done) {
this->set_origin(0., 0.);
m_avoid_crossing_perimeters.use_external_mp();
for (const ExtrusionEntity* brim_entity : print.brim().entities) {
for (const ExtrusionEntity* brim_entity : print.brim().entities()) {
//if first layer, ask for a bigger lift for travel to each brim, to be on the safe side
set_extra_lift(m_last_layer_z, layer.id(), print.config(), m_writer, extruder_id);
gcode += this->extrude_entity(*brim_entity, "Brim", m_config.support_material_speed.value);
@ -2583,10 +2583,10 @@ void GCode::process_layer(
this->set_origin(unscale(print_object->instances()[single_object_instance_idx].shift));
if (this->m_layer != nullptr && (this->m_layer->id() < m_config.skirt_height || print.has_infinite_skirt() )) {
if(first_layer && print.skirt_first_layer())
for (const ExtrusionEntity* ee : print_object->skirt_first_layer()->entities)
for (const ExtrusionEntity* ee : print_object->skirt_first_layer()->entities())
gcode += this->extrude_entity(*ee, "", m_config.support_material_speed.value);
else
for (const ExtrusionEntity *ee : print_object->skirt().entities)
for (const ExtrusionEntity *ee : print_object->skirt().entities())
gcode += this->extrude_entity(*ee, "", m_config.support_material_speed.value);
}
}
@ -2598,7 +2598,7 @@ void GCode::process_layer(
this->set_origin(unscale(print_object->instances()[single_object_instance_idx].shift));
if (this->m_layer != nullptr && this->m_layer->id() == 0) {
m_avoid_crossing_perimeters.use_external_mp(true);
for (const ExtrusionEntity *ee : print_object->brim().entities)
for (const ExtrusionEntity *ee : print_object->brim().entities())
gcode += this->extrude_entity(*ee, "brim", m_config.support_material_speed.value);
m_avoid_crossing_perimeters.use_external_mp(false);
m_avoid_crossing_perimeters.disable_once();
@ -3557,12 +3557,12 @@ std::string GCode::extrude_entity(const ExtrusionEntity &entity, const std::stri
void GCode::use(const ExtrusionEntityCollection &collection) {
if (!collection.can_sort() || collection.role() == erMixed) {
for (const ExtrusionEntity* next_entity : collection.entities) {
for (const ExtrusionEntity* next_entity : collection.entities()) {
next_entity->visit(*this);
}
} else {
ExtrusionEntityCollection chained = collection.chained_path_from(m_last_pos);
for (const ExtrusionEntity* next_entity : chained.entities) {
for (const ExtrusionEntity* next_entity : chained.entities()) {
next_entity->visit(*this);
}
}
@ -3719,12 +3719,12 @@ std::string GCode::extrude_ironing(const Print& print, const std::vector<ObjectB
std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fills)
{
std::string gcode;
if (! support_fills.entities.empty()) {
if (! support_fills.entities().empty()) {
const char *support_label = "support material";
const char *support_interface_label = "support material interface";
const double support_speed = m_config.support_material_speed.value;
const double support_interface_speed = m_config.support_material_interface_speed.get_abs_value(support_speed);
for (const ExtrusionEntity *ee : support_fills.entities) {
for (const ExtrusionEntity *ee : support_fills.entities()) {
ExtrusionRole role = ee->role();
assert(role == erSupportMaterial || role == erSupportMaterialInterface || role == erMixed);
if (const ExtrusionEntityCollection* coll = dynamic_cast<const ExtrusionEntityCollection*>(ee)) {
@ -4645,7 +4645,7 @@ Point GCode::gcode_to_point(const Vec2d &point) const
scale_(point(1) - m_origin(1) + extruder_offset(1)));
}
// Goes through by_region std::vector and returns reference to a subvector of entities, that are to be printed
// Goes through by_region std::vector and returns reference to a subvector of entities(), that are to be printed
// during infill/perimeter wiping, or normally (depends on wiping_entities parameter)
// Fills in by_region_per_copy_cache and returns its reference.
const std::vector<GCode::ObjectByExtruder::Island::Region>& GCode::ObjectByExtruder::Island::by_region_per_copy(std::vector<Region> &by_region_per_copy_cache, unsigned int copy, uint16_t extruder, bool wiping_entities) const
@ -4703,7 +4703,7 @@ const std::vector<GCode::ObjectByExtruder::Island::Region>& GCode::ObjectByExtru
return by_region_per_copy_cache;
}
// This function takes the eec and appends its entities to either perimeters or infills of this Region (depending on the first parameter)
// This function takes the eec and appends its entities() to either perimeters or infills of this Region (depending on the first parameter)
// It also saves pointer to ExtruderPerCopy struct (for each entity), that holds information about which extruders should be used for which copy.
void GCode::ObjectByExtruder::Island::Region::append(const Type type, const ExtrusionEntityCollection* eec, const WipingExtrusions::ExtruderPerCopy* copies_extruder)
{
@ -4728,15 +4728,17 @@ void GCode::ObjectByExtruder::Island::Region::append(const Type type, const Extr
throw Slic3r::InvalidArgument("Unknown parameter!");
}
// First we append the entities, there are eec->entities.size() of them:
//don't do fill->entities because it will discard no_sort, we must use flatten(preserve_ordering = true)
// this method will encapsulate every no_sort into an other collection, so we can get the entities directly.
ExtrusionEntitiesPtr entities = eec->flatten(true).entities;
// First we append the entities, there are eec->entities().size() of them:
//don't do fill->entities() because it will discard no_sort, we must use flatten(preserve_ordering = true)
// this method will encapsulate every no_sort into an other collection, so we can get the entities() directly.
ExtrusionEntityCollection coll = eec->flatten(true);
size_t old_size = perimeters_or_infills->size();
size_t new_size = old_size + entities.size();
size_t new_size = old_size + coll.entities().size();
perimeters_or_infills->reserve(new_size);
for (auto* ee : entities)
perimeters_or_infills->emplace_back(ee);
for (ExtrusionEntity* ee : coll.set_entities())
perimeters_or_infills->push_back(ee);
//hack for change of ownership
coll.set_entities().clear();
if (copies_extruder != nullptr) {
// Don't reallocate overrides if not needed.

View File

@ -257,12 +257,12 @@ private:
struct Island
{
struct Region {
// Non-owned references to LayerRegion::perimeters::entities
// Non-owned references to LayerRegion::perimeters::entities()
// std::vector<const ExtrusionEntity*> would be better here, but there is no way in C++ to convert from std::vector<T*> std::vector<const T*> without copying.
ExtrusionEntitiesPtr perimeters;
// Non-owned references to LayerRegion::fills::entities
// Non-owned references to LayerRegion::fills::entities()
ExtrusionEntitiesPtr infills;
// Non-owned references to LayerRegion::ironing::entities
// Non-owned references to LayerRegion::ironing::entities()
ExtrusionEntitiesPtr ironings;
std::vector<const WipingExtrusions::ExtruderPerCopy*> infills_overrides;
@ -275,7 +275,7 @@ private:
IRONING,
};
// Appends perimeter/infill entities and writes don't indices of those that are not to be extruder as part of perimeter/infill wiping
// Appends perimeter/infill entities() and writes don't indices of those that are not to be extruder as part of perimeter/infill wiping
void append(const Type type, const ExtrusionEntityCollection* eec, const WipingExtrusions::ExtruderPerCopy* copy_extruders);
};

View File

@ -73,7 +73,7 @@ static BoundingBoxf extrusionentity_extents(const ExtrusionEntity *extrusion_ent
static inline BoundingBoxf extrusionentity_extents(const ExtrusionEntityCollection &extrusion_entity_collection)
{
BoundingBoxf bbox;
for (const ExtrusionEntity *extrusion_entity : extrusion_entity_collection.entities)
for (const ExtrusionEntity *extrusion_entity : extrusion_entity_collection.entities())
bbox.merge(extrusionentity_extents(extrusion_entity));
return bbox;
}
@ -114,13 +114,13 @@ BoundingBoxf get_print_object_extrusions_extents(const PrintObject &print_object
BoundingBoxf bbox_this;
for (const LayerRegion *layerm : layer->regions()) {
bbox_this.merge(extrusionentity_extents(layerm->perimeters));
for (const ExtrusionEntity *ee : layerm->fills.entities)
for (const ExtrusionEntity *ee : layerm->fills.entities())
// fill represents infill extrusions of a single island.
bbox_this.merge(extrusionentity_extents(*dynamic_cast<const ExtrusionEntityCollection*>(ee)));
}
const SupportLayer *support_layer = dynamic_cast<const SupportLayer*>(layer);
if (support_layer)
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities())
bbox_this.merge(extrusionentity_extents(extrusion_entity));
for (const PrintInstance &instance : print_object.instances()) {
BoundingBoxf bbox_translated(bbox_this);

View File

@ -64,7 +64,7 @@ uint16_t LayerTools::extruder(const ExtrusionEntityCollection &extrusions, const
// 1 based extruder ID.
uint16_t extruder = ((this->extruder_override == 0) ?
(is_infill(extrusions.role()) ?
(is_solid_infill(extrusions.entities.front()->role()) ? region.config().solid_infill_extruder : region.config().infill_extruder) :
(is_solid_infill(extrusions.entities().front()->role()) ? region.config().solid_infill_extruder : region.config().infill_extruder) :
region.config().perimeter_extruder.value) :
this->extruder_override);
return (extruder == 0) ? 0 : extruder - 1;
@ -209,12 +209,12 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
continue;
const PrintRegion &region = *object.print()->regions()[region_id];
if (! layerm->perimeters.entities.empty()) {
if (! layerm->perimeters.entities().empty()) {
bool something_nonoverriddable = true;
if (m_print_config_ptr) { // in this case complete_objects is false (see ToolOrdering constructors)
something_nonoverriddable = false;
for (const auto& eec : layerm->perimeters.entities) // let's check if there are nonoverriddable entities
for (const ExtrusionEntity* eec : layerm->perimeters.entities()) // let's check if there are nonoverriddable entities()
if (!layer_tools.wiping_extrusions().is_overriddable_and_mark(dynamic_cast<const ExtrusionEntityCollection&>(*eec), *m_print_config_ptr, object, region))
something_nonoverriddable = true;
}
@ -228,10 +228,10 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto
bool has_infill = false;
bool has_solid_infill = false;
bool something_nonoverriddable = false;
for (const ExtrusionEntity *ee : layerm->fills.entities) {
for (const ExtrusionEntity *ee : layerm->fills.entities()) {
// fill represents infill extrusions of a single island.
const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
ExtrusionRole role = fill->entities.empty() ? erNone : fill->entities.front()->role();
ExtrusionRole role = fill->entities().empty() ? erNone : fill->entities().front()->role();
if (is_solid_infill(role))
has_solid_infill = true;
else if (role != erNone)
@ -636,7 +636,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, uint16_t old_
bool wipe_into_infill_only = ! object->config().wipe_into_objects && region.config().wipe_into_infill;
if (region.config().infill_first != perimeters_done || wipe_into_infill_only) {
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities) { // iterate through all infill Collections
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities()) { // iterate through all infill Collections
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (!is_overriddable(*fill, print.config(), *object, region))
@ -660,7 +660,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, uint16_t old_
// Now the same for perimeters - see comments above for explanation:
if (object->config().wipe_into_objects && region.config().infill_first == perimeters_done)
{
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities) {
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities()) {
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (is_overriddable(*fill, print.config(), *object, region) && !is_entity_overridden(fill, copy) && fill->total_volume() > min_infill_volume) {
set_extruder_override(fill, copy, new_extruder, num_of_copies);
@ -680,7 +680,7 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, uint16_t old_
// Called after all toolchanges on a layer were mark_infill_overridden. There might still be overridable entities,
// Called after all toolchanges on a layer were mark_infill_overridden. There might still be overridable entities(),
// that were not actually overridden. If they are part of a dedicated object, printing them with the extruder
// they were initially assigned to might mean violating the perimeter-infill order. We will therefore go through
// them again and make sure we override it.
@ -707,7 +707,7 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
if (!region.config().wipe_into_infill && !object->config().wipe_into_objects)
continue;
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities) { // iterate through all infill Collections
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->fills.entities()) { // iterate through all infill Collections
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (!is_overriddable(*fill, print.config(), *object, region)
@ -730,7 +730,8 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
}
// Now the same for perimeters - see comments above for explanation:
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities) { // iterate through all perimeter Collections
for (const ExtrusionEntity* ee : this_layer->regions()[region_id]->perimeters.entities()) {
// iterate through all perimeter Collections
auto* fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (is_overriddable(*fill, print.config(), *object, region) && ! is_entity_overridden(fill, copy))
set_extruder_override(fill, copy, (region.config().infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies);

View File

@ -35,7 +35,7 @@ public:
// This is called from GCode::process_layer - see implementation for further comments:
const ExtruderPerCopy* get_extruder_overrides(const ExtrusionEntity* entity, int correct_extruder_id, size_t num_of_copies);
// This function goes through all infill entities, decides which ones will be used for wiping and
// This function goes through all infill entities(), decides which ones will be used for wiping and
// marks them by the extruder id. Returns volume that remains to be wiped on the wipe tower:
float mark_wiping_extrusions(const Print& print, uint16_t old_extruder, uint16_t new_extruder, float volume_to_wipe);

View File

@ -86,7 +86,7 @@ public:
void export_region_fill_surfaces_to_svg_debug(const char *name) const;
// Is there any valid extrusion assigned to this LayerRegion?
bool has_extrusions() const { return !this->perimeters.entities.empty() || !this->fills.entities.empty() || !this->ironings.entities.empty() || !this->thin_fills.entities.empty(); }
bool has_extrusions() const { return !this->perimeters.entities().empty() || !this->fills.entities().empty() || !this->ironings.entities().empty() || !this->thin_fills.entities().empty(); }
protected:
friend class Layer;

View File

@ -926,34 +926,34 @@ void PerimeterGenerator::process()
}
// at this point, all loops should be in contours[0] (= contours.front() )
// collection of loops to add into loops
ExtrusionEntityCollection entities;
ExtrusionEntityCollection peri_entities;
if (config->perimeter_loop.value) {
//onlyone_perimter = >fusion all perimeterLoops
//onlyone_perimeter = >fusion all perimeterLoops
for (PerimeterGeneratorLoop& loop : contours.front()) {
ExtrusionLoop extr_loop = this->_traverse_and_join_loops(loop, get_all_Childs(loop), loop.polygon.points.front());
//ExtrusionLoop extr_loop = this->_traverse_and_join_loops_old(loop, loop.polygon.points.front(), true);
extr_loop.paths.back().polyline.points.push_back(extr_loop.paths.front().polyline.points.front());
entities.append(extr_loop);
peri_entities.append(extr_loop);
}
// append thin walls
if (!thin_walls_thickpolys.empty()) {
if (this->object_config->thin_walls_merge) {
_merge_thin_walls(entities, thin_walls_thickpolys);
_merge_thin_walls(peri_entities, thin_walls_thickpolys);
} else {
ExtrusionEntityCollection tw = thin_variable_width
(thin_walls_thickpolys, erThinWall, this->ext_perimeter_flow, std::max(ext_perimeter_width / 4, scale_t(this->print_config->resolution)));
entities.append(tw.entities);
peri_entities.append(tw.entities());
}
thin_walls_thickpolys.clear();
}
} else {
if (this->object_config->thin_walls_merge) {
ThickPolylines no_thin_walls;
entities = this->_traverse_loops(contours.front(), no_thin_walls);
_merge_thin_walls(entities, thin_walls_thickpolys);
peri_entities = this->_traverse_loops(contours.front(), no_thin_walls);
_merge_thin_walls(peri_entities, thin_walls_thickpolys);
} else {
entities = this->_traverse_loops(contours.front(), thin_walls_thickpolys);
peri_entities = this->_traverse_loops(contours.front(), thin_walls_thickpolys);
}
}
@ -968,68 +968,62 @@ void PerimeterGenerator::process()
if (this->config->external_perimeters_hole.value || brim_first_layer) {
//reverse only not-thin wall
ExtrusionEntityCollection coll2;
for (const auto loop : entities.entities) {
for (const ExtrusionEntity* loop : peri_entities.entities()) {
if ( (loop->is_loop() && loop->role() != erThinWall)) {
coll2.entities.push_back(loop);
coll2.append(*loop);
}
}
coll2.reverse();
for (const auto loop : entities.entities) {
for (const ExtrusionEntity* loop : peri_entities.entities()) {
if (!((loop->is_loop() && loop->role() != erThinWall))) {
coll2.entities.push_back(loop);
coll2.append(*loop);
}
}
//note: this hacky thing is possible because coll2.entities contains in fact entities's entities
//if you does entities = coll2, you'll delete entities's entities and then you have nothing.
entities.entities = coll2.entities;
//and you have to empty coll2 or it will delete his content, hence crashing our hack
coll2.entities.clear();
//note: this hacky thing is possible because coll2.entities contains in fact peri_entities's entities
//if you does peri_entities = coll2, you'll delete peri_entities's entities() and then you have nothing.
peri_entities = std::move(coll2);
} else {
//reverse only not-hole perimeters
ExtrusionEntityCollection coll2;
for (const auto loop : entities.entities) {
for (const ExtrusionEntity* loop : peri_entities.entities()) {
if ((loop->is_loop() && loop->role() != erThinWall) && !(((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) != 0) {
coll2.entities.push_back(loop);
coll2.append(*loop);
}
}
coll2.reverse();
for (const auto loop : entities.entities) {
if (!((loop->is_loop() && loop->role() != erThinWall) && (((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) != 0)) {
coll2.entities.push_back(loop);
for (const ExtrusionEntity* loop : peri_entities.entities()) {
if (!((loop->is_loop() && loop->role() != erThinWall) && !(((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) != 0)) {
coll2.append(*loop);
}
}
//note: this hacky thing is possible because coll2.entities contains in fact entities's entities
//if you does entities = coll2, you'll delete entities's entities and then you have nothing.
entities.entities = coll2.entities;
//and you have to empty coll2 or it will delete his content, hence crashing our hack
coll2.entities.clear();
//if you does peri_entities = coll2, you'll delete peri_entities's entities and then you have nothing.
peri_entities = std::move(coll2);
}
} else if (this->config->external_perimeters_hole.value) {
//reverse the hole, and put them in first place.
ExtrusionEntityCollection coll2;
for (const auto loop : entities.entities) {
for (const ExtrusionEntity* loop : peri_entities.entities()) {
if ((loop->is_loop() && loop->role() != erThinWall) && (((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) != 0) {
coll2.entities.push_back(loop);
coll2.append(*loop);
}
}
coll2.reverse();
for (const auto loop : entities.entities) {
for (const ExtrusionEntity* loop : peri_entities.entities()) {
if (!((loop->is_loop() && loop->role() != erThinWall) && (((ExtrusionLoop*)loop)->loop_role() & ExtrusionLoopRole::elrHole) != 0)) {
coll2.entities.push_back(loop);
coll2.append(*loop);
}
}
//note: this hacky thing is possible because coll2.entities contains in fact entities's entities
//if you does entities = coll2, you'll delete entities's entities and then you have nothing.
entities.entities = coll2.entities;
//and you have to empty coll2 or it will delete his content, hence crashing our hack
coll2.entities.clear();
//note: this hacky thing is possible because coll2.entities contains in fact peri_entities's entities
//if you does peri_entities = coll2, you'll delete peri_entities's entities and then you have nothing.
peri_entities = std::move(coll2);
}
}
// append perimeters for this slice as a collection
if (!entities.empty()) {
if (!peri_entities.empty()) {
//move it, to avoid to clone evrything and then delete it
this->loops->entities.emplace_back(new ExtrusionEntityCollection(std::move(entities)));
this->loops->append(peri_entities);
}
} // for each loop of an island
@ -1116,7 +1110,7 @@ void PerimeterGenerator::process()
// svg.draw(polylines, "blue");
// svg.Close();
//}
this->gap_fill->append(gap_fill.entities);
this->gap_fill->append(gap_fill.entities());
/* Make sure we don't infill narrow parts that are already gap-filled
(we only consider this surface's gaps to reduce the diff() complexity).
Growing actual extrusions ensures that gaps not filled by medial axis
@ -1130,7 +1124,6 @@ void PerimeterGenerator::process()
// the diff(last, gap) will be done after, as we have to keep the last un-gapped to avoid unneeded gap/infill offset
}
}
//TODO: if a gapfill extrusion is a loop and with width always >= perimeter width then change the type to perimeter and put it at the right place in the loops vector.
// create one more offset to be used as boundary for fill
// we offset by half the perimeter spacing (to get to the actual infill boundary)
@ -1460,7 +1453,7 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
{
// loops is an arrayref of ::Loop objects
// turn each one into an ExtrusionLoop object
ExtrusionEntityCollection coll;
ExtrusionEntitiesPtr coll;
for (const PerimeterGeneratorLoop &loop : loops) {
bool is_external = loop.is_external();
@ -1502,20 +1495,20 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
paths.push_back(path);
}
coll.append(ExtrusionLoop(paths, loop_role));
coll.push_back(new ExtrusionLoop(paths, loop_role));
}
// append thin walls to the nearest-neighbor search (only for first iteration)
if (!thin_walls.empty()) {
ExtrusionEntityCollection tw = thin_variable_width(thin_walls, erThinWall, this->ext_perimeter_flow, std::max(ext_perimeter_flow.scaled_width() / 4, scale_t(this->print_config->resolution)));
coll.append(tw.entities);
coll.insert(coll.end(), tw.entities().begin(), tw.entities().end());
thin_walls.clear();
}
// traverse children and build the final collection
Point zero_point(0, 0);
//result is [idx, needReverse] ?
std::vector<std::pair<size_t, bool>> chain = chain_extrusion_entities(coll.entities, &zero_point);
std::vector<std::pair<size_t, bool>> chain = chain_extrusion_entities(coll, &zero_point);
ExtrusionEntityCollection coll_out;
if (chain.empty()) return coll_out;
@ -1543,34 +1536,34 @@ ExtrusionEntityCollection PerimeterGenerator::_traverse_loops(
if (idx.first >= loops.size()) {
// this is a thin wall
// let's get it from the sorted collection as it might have been reversed
coll_out.entities.reserve(coll_out.entities.size() + 1);
coll_out.entities.emplace_back(coll.entities[idx.first]);
coll.entities[idx.first] = nullptr;
coll_out.set_entities().reserve(coll_out.entities().size() + 1);
coll_out.set_entities().emplace_back(coll[idx.first]);
coll[idx.first] = nullptr;
if (idx.second)
coll_out.entities.back()->reverse();
coll_out.entities().back()->reverse();
//if thin extrusion is a loop, make it ccw like a normal contour.
if (ExtrusionLoop* loop = dynamic_cast<ExtrusionLoop*>(coll_out.entities.back())) {
if (ExtrusionLoop* loop = dynamic_cast<ExtrusionLoop*>(coll_out.entities().back())) {
loop->make_counter_clockwise();
}
} else {
const PerimeterGeneratorLoop &loop = loops[idx.first];
assert(thin_walls.empty());
ExtrusionEntityCollection children = this->_traverse_loops(loop.children, thin_walls);
coll_out.entities.reserve(coll_out.entities.size() + children.entities.size() + 1);
ExtrusionLoop *eloop = static_cast<ExtrusionLoop*>(coll.entities[idx.first]);
coll.entities[idx.first] = nullptr;
coll_out.set_entities().reserve(coll_out.entities().size() + children.entities().size() + 1);
ExtrusionLoop *eloop = static_cast<ExtrusionLoop*>(coll[idx.first]);
coll[idx.first] = nullptr;
if (loop.is_contour) {
//note: this->layer->id() % 2 == 1 already taken into account in the is_steep_overhang compute (to save time).
if (loop.is_steep_overhang && this->layer->id() % 2 == 1)
eloop->make_clockwise();
else
eloop->make_counter_clockwise();
coll_out.append(std::move(children.entities));
coll_out.append(std::move(children.entities()));
coll_out.append(*eloop);
} else {
eloop->make_clockwise();
coll_out.append(*eloop);
coll_out.append(std::move(children.entities));
coll_out.append(std::move(children.entities()));
}
}
}
@ -1595,7 +1588,7 @@ void PerimeterGenerator::_merge_thin_walls(ExtrusionEntityCollection &extrusions
this->use(path);
}
virtual void use(ExtrusionEntityCollection &collection) override {
for (ExtrusionEntity *entity : collection.entities)
for (ExtrusionEntity *entity : collection.entities())
entity->visit(*this);
}
};
@ -1662,7 +1655,7 @@ void PerimeterGenerator::_merge_thin_walls(ExtrusionEntityCollection &extrusions
virtual void use(ExtrusionEntityCollection &collection) override {
collection.set_can_sort_reverse(true, true);
//for each loop? (or other collections)
for (ExtrusionEntity *entity : collection.entities)
for (ExtrusionEntity *entity : collection.entities())
entity->visit(*this);
}
};
@ -1703,7 +1696,7 @@ void PerimeterGenerator::_merge_thin_walls(ExtrusionEntityCollection &extrusions
//create thin wall path exttrusion
ExtrusionEntityCollection tws = thin_variable_width({ tw }, erThinWall, this->ext_perimeter_flow, std::max(ext_perimeter_flow.scaled_width() / 4, scale_t(this->print_config->resolution)));
ChangeFlow change_flow;
if (tws.entities.size() == 1 && tws.entities[0]->is_loop()) {
if (tws.entities().size() == 1 && tws.entities()[0]->is_loop()) {
//loop, just add it
change_flow.percent_extrusion = 1;
change_flow.use(tws);
@ -1739,7 +1732,7 @@ void PerimeterGenerator::_merge_thin_walls(ExtrusionEntityCollection &extrusions
//now add thinwalls that have no anchor (make them reversable)
ExtrusionEntityCollection tws = thin_variable_width(not_added, erThinWall, this->ext_perimeter_flow, std::max(ext_perimeter_flow.scaled_width() / 4, scale_t(this->print_config->resolution)));
extrusions.append(tws.entities);
extrusions.append(tws.entities());
}
PerimeterIntersectionPoint

View File

@ -2008,7 +2008,7 @@ void Print::_make_skirt(const PrintObjectPtrs &objects, ExtrusionEntityCollectio
for (const SupportLayer *layer : object->support_layers()) {
if (layer->print_z > skirt_height_z)
break;
for (const ExtrusionEntity *extrusion_entity : layer->support_fills.entities) {
for (const ExtrusionEntity *extrusion_entity : layer->support_fills.entities()) {
Polylines poly;
extrusion_entity->collect_polylines(poly);
for (const Polyline& polyline : poly)
@ -2020,7 +2020,7 @@ void Print::_make_skirt(const PrintObjectPtrs &objects, ExtrusionEntityCollectio
// get first layer support
if (!object->support_layers().empty() && object->support_layers().front()->print_z == object->m_layers[0]->print_z) {
Points support_points;
for (const ExtrusionEntity* extrusion_entity : object->support_layers().front()->support_fills.entities) {
for (const ExtrusionEntity* extrusion_entity : object->support_layers().front()->support_fills.entities()) {
Polylines poly;
extrusion_entity->collect_polylines(poly);
for (const Polyline& polyline : poly)
@ -2260,63 +2260,67 @@ void Print::_extrude_brim_from_tree(std::vector<std::vector<BrimLoop>>& loops, c
if (!i_have_line && to_cut.children.empty()) {
//nothing
} else if (i_have_line && to_cut.children.empty()) {
ExtrusionEntitiesPtr to_add;
for(Polyline& line : to_cut.lines)
if (line.points.back() == line.points.front()) {
ExtrusionPath path(erSkirt, mm3_per_mm, width, height);
path.polyline.points = line.points;
parent->entities.emplace_back(new ExtrusionLoop(std::move(path), elrSkirt));
to_add.emplace_back(new ExtrusionLoop(std::move(path), elrSkirt));
} else {
ExtrusionPath* extrusion_path = new ExtrusionPath(erSkirt, mm3_per_mm, width, height);
parent->entities.push_back(extrusion_path);
to_add.emplace_back(extrusion_path);
extrusion_path->polyline = line;
}
parent->append(std::move(to_add));
} else if (!i_have_line && !to_cut.children.empty()) {
if (to_cut.children.size() == 1) {
(*extrude_ptr)(to_cut.children[0], parent);
} else {
ExtrusionEntityCollection* mycoll = new ExtrusionEntityCollection();
//mycoll->no_sort = true;
parent->entities.push_back(mycoll);
for (BrimLoop& child : to_cut.children)
(*extrude_ptr)(child, mycoll);
//remove un-needed collection if possible
if (mycoll->entities.size() == 1) {
parent->entities.back() = mycoll->entities.front();
mycoll->entities.clear();
if (mycoll->entities().size() == 1) {
parent->append(*mycoll->entities().front());
delete mycoll;
} else if (mycoll->entities.size() == 0) {
parent->remove(parent->entities.size() - 1);
} else if (mycoll->entities().size() == 0) {
delete mycoll;
} else {
parent->append(ExtrusionEntitiesPtr{ mycoll });
}
}
} else {
ExtrusionEntityCollection* print_me_first = new ExtrusionEntityCollection();
parent->entities.push_back(print_me_first);
ExtrusionEntitiesPtr to_add;
to_add.emplace_back(print_me_first);
print_me_first->set_can_sort_reverse(false, false);
for (Polyline& line : to_cut.lines)
if (line.points.back() == line.points.front()) {
ExtrusionPath path(erSkirt, mm3_per_mm, width, height);
path.polyline.points = line.points;
print_me_first->entities.emplace_back(new ExtrusionLoop(std::move(path), elrSkirt));
to_add.emplace_back(new ExtrusionLoop(std::move(path), elrSkirt));
} else {
ExtrusionPath* extrusion_path = new ExtrusionPath(erSkirt, mm3_per_mm, width, height);
print_me_first->entities.push_back(extrusion_path);
to_add.emplace_back(extrusion_path);
extrusion_path->polyline = line;
}
parent->append(std::move(to_add));
if (to_cut.children.size() == 1) {
(*extrude_ptr)(to_cut.children[0], print_me_first);
} else {
ExtrusionEntityCollection* children = new ExtrusionEntityCollection();
//children->no_sort = true;
print_me_first->entities.push_back(children);
for (BrimLoop& child : to_cut.children)
(*extrude_ptr)(child, children);
//remove un-needed collection if possible
if (children->entities.size() == 1) {
print_me_first->entities.back() = children->entities.front();
children->entities.clear();
if (children->entities().size() == 1) {
parent->append(*children->entities().front());
delete children;
} else if (children->entities.size() == 0) {
print_me_first->remove(parent->entities.size() - 1);
} else if (children->entities().size() == 0) {
delete children;
} else {
parent->append(ExtrusionEntitiesPtr{ children });
}
}
}
@ -2573,7 +2577,7 @@ void Print::_make_brim_ears(const Flow &flow, const PrintObjectPtrs &objects, Ex
//push into extrusions
extrusion_entities_append_paths(
out.entities,
out.set_entities(),
lines_sorted,
erSkirt,
float(flow.mm3_per_mm()),
@ -2614,7 +2618,7 @@ void Print::_make_brim_ears(const Flow &flow, const PrintObjectPtrs &objects, Ex
filler->init_spacing(flow.spacing(), fill_params);
for (const ExPolygon &expoly : new_brim_area) {
Surface surface(stPosInternal | stDensSparse, expoly);
filler->fill_surface_extrusion(&surface, fill_params, out.entities);
filler->fill_surface_extrusion(&surface, fill_params, out.set_entities());
}
unbrimmable.insert(unbrimmable.end(), new_brim_area.begin(), new_brim_area.end());

View File

@ -1979,7 +1979,7 @@ template<class T> static inline T chain_path_items(const Points &points, const T
return out;
}
ClipperLib::PolyNodes chain_clipper_polynodes(const Points &points, const ClipperLib::PolyNodes &items)
std::vector<ClipperLib::PolyNode*> chain_clipper_polynodes(const Points &points, const std::vector<ClipperLib::PolyNode*> &items)
{
return chain_path_items(points, items);
}

View File

@ -789,9 +789,9 @@ namespace SupportMaterialInternal {
}
static bool has_bridging_perimeters(const ExtrusionEntityCollection &perimeters)
{
for (const ExtrusionEntity *ee : perimeters.entities) {
for (const ExtrusionEntity *ee : perimeters.entities()) {
if (ee->is_collection()) {
for (const ExtrusionEntity *ee2 : static_cast<const ExtrusionEntityCollection*>(ee)->entities) {
for (const ExtrusionEntity *ee2 : static_cast<const ExtrusionEntityCollection*>(ee)->entities()) {
//assert(! ee2->is_collection()); // there are loops for perimeters and collections for thin walls !!
if (ee2->is_loop())
if (has_bridging_perimeters(*static_cast<const ExtrusionLoop*>(ee2)))
@ -804,7 +804,7 @@ namespace SupportMaterialInternal {
}
static bool has_bridging_fills(const ExtrusionEntityCollection &fills)
{
for (const ExtrusionEntity *ee : fills.entities) {
for (const ExtrusionEntity *ee : fills.entities()) {
if (ee->is_collection()) {
if(has_bridging_fills(*static_cast<const ExtrusionEntityCollection*>(ee)))
return true;
@ -857,7 +857,7 @@ namespace SupportMaterialInternal {
{
for (const ExtrusionEntity *ee : perimeters) {
if (ee->is_collection()) {
collect_bridging_perimeter_areas(static_cast<const ExtrusionEntityCollection*>(ee)->entities, expansion_scaled, out);
collect_bridging_perimeter_areas(static_cast<const ExtrusionEntityCollection*>(ee)->entities(), expansion_scaled, out);
} else if (ee->is_loop())
collect_bridging_perimeter_areas(*static_cast<const ExtrusionLoop*>(ee), expansion_scaled, out);
}
@ -2147,7 +2147,7 @@ void PrintObjectSupportMaterial::trim_support_layers_by_object(
offset(to_expolygons(region->fill_surfaces.filter_by_type(stPosBottom | stDensSolid | stModBridge)),
gap_xy_scaled, SUPPORT_SURFACES_OFFSET_PARAMETERS));
if (region->region()->config().overhangs_width.value > 0)
SupportMaterialInternal::collect_bridging_perimeter_areas(region->perimeters.entities, gap_xy_scaled, polygons_trimming);
SupportMaterialInternal::collect_bridging_perimeter_areas(region->perimeters.entities(), gap_xy_scaled, polygons_trimming);
}
if (! some_region_overlaps)
break;
@ -2421,8 +2421,8 @@ struct MyLayerExtruded
*m_polygons_to_extrude = union_(*m_polygons_to_extrude, true);
}
// 2) Merge the extrusions.
this->extrusions.entities.insert(this->extrusions.entities.end(), other.extrusions.entities.begin(), other.extrusions.entities.end());
other.extrusions.entities.clear();
this->extrusions.set_entities().insert(this->extrusions.entities().end(), other.extrusions.entities().begin(), other.extrusions.entities().end());
other.extrusions.set_entities().clear();
// 3) Merge the infill polygons.
Slic3r::polygons_append(this->layer->polygons, std::move(other.layer->polygons));
this->layer->polygons = union_(this->layer->polygons, true);
@ -2671,7 +2671,7 @@ void LoopInterfaceProcessor::generate(MyLayerExtruded &top_contact_layer, const
// Transform loops into ExtrusionPath objects.
extrusion_entities_append_paths(
top_contact_layer.extrusions.entities,
top_contact_layer.extrusions.set_entities(),
std::move(loop_lines),
erSupportMaterialInterface, flow.mm3_per_mm(), flow.width, flow.height);
}
@ -2699,8 +2699,8 @@ public:
virtual void use(const ExtrusionMultiPath3D &multipath) override { if (!multipath.paths.empty()) extrusion_path_template = &multipath.paths.front(); }
virtual void use(const ExtrusionLoop &loop) override { if (!loop.paths.empty()) extrusion_path_template = &loop.paths.front(); }
virtual void use(const ExtrusionEntityCollection &collection) override {
auto it = collection.entities.begin();
while (extrusion_path_template == nullptr && it != collection.entities.end()) {
auto it = collection.entities().begin();
while (extrusion_path_template == nullptr && it != collection.entities().end()) {
(*it)->visit(*this);
++it;
}
@ -2730,7 +2730,7 @@ void modulate_extrusion_by_overlapping_layers(
// Get the initial extrusion parameters.
GetFirstPath getFirstPathVisitor;
flatten_extrusions_in_out.entities.front()->visit(getFirstPathVisitor);
flatten_extrusions_in_out.entities().front()->visit(getFirstPathVisitor);
const ExtrusionPath *extrusion_path_template = getFirstPathVisitor.extrusion_path_template;
assert(extrusion_path_template != nullptr);
ExtrusionRole extrusion_role = extrusion_path_template->role();
@ -2806,7 +2806,7 @@ void modulate_extrusion_by_overlapping_layers(
// Collect the paths of this_layer.
{
Polylines &polylines = path_fragments.back().polylines;
for (ExtrusionEntitiesPtr::const_iterator it = flatten_extrusions_in_out.entities.begin(); it != flatten_extrusions_in_out.entities.end(); ++it) {
for (ExtrusionEntitiesPtr::const_iterator it = flatten_extrusions_in_out.entities().begin(); it != flatten_extrusions_in_out.entities().end(); ++it) {
Polylines polylines_from_entity = (*it)->as_polylines();
for (Polyline &polyline : polylines_from_entity) {
polylines.emplace_back(std::move(polyline));
@ -2947,18 +2947,18 @@ void modulate_extrusion_by_overlapping_layers(
if (!multipath.paths.empty()) {
if (multipath.paths.size() == 1) {
// This path was not fragmented.
extrusions_in_out.entities.push_back(new ExtrusionPath(std::move(multipath.paths.front())));
extrusions_in_out.append(ExtrusionEntitiesPtr{ new ExtrusionPath(std::move(multipath.paths.front())) });
} else {
// This path was fragmented. Copy the collection as a whole object, so the order inside the collection will not be changed
// during the chaining of extrusions_in_out.
extrusions_in_out.entities.push_back(new ExtrusionMultiPath(std::move(multipath)));
extrusions_in_out.append(ExtrusionEntitiesPtr{ new ExtrusionMultiPath(std::move(multipath)) });
}
}
}
// If there are any non-consumed fragments, add them separately.
//FIXME this shall not happen, if the Clipper works as expected and all paths split to fragments could be re-connected.
for (auto it_fragment = path_fragments.begin(); it_fragment != path_fragments.end(); ++ it_fragment)
extrusion_entities_append_paths(extrusions_in_out.entities, std::move(it_fragment->polylines), extrusion_role, it_fragment->mm3_per_mm, it_fragment->width, it_fragment->height);
extrusion_entities_append_paths(extrusions_in_out.set_entities(), std::move(it_fragment->polylines), extrusion_role, it_fragment->mm3_per_mm, it_fragment->width, it_fragment->height);
}
void PrintObjectSupportMaterial::generate_toolpaths(
@ -3039,7 +3039,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
{
assert(support_layer_id < raft_layers.size());
SupportLayer &support_layer = *object.support_layers()[support_layer_id];
assert(support_layer.support_fills.entities.empty());
assert(support_layer.support_fills.entities().empty());
MyLayer &raft_layer = *raft_layers[support_layer_id];
std::unique_ptr<Fill> filler_interface = std::unique_ptr<Fill>(Fill::new_from_type(interface_pattern));
@ -3068,7 +3068,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
// TODO: use offset2_ex()
to_infill = offset_ex(to_infill, double(- 0.4 * flow.scaled_spacing()));
extrusion_entities_append_paths(
support_layer.support_fills.entities,
support_layer.support_fills.set_entities(),
to_polylines(std::move(to_infill_polygons)),
erSupportMaterial, flow.mm3_per_mm(), flow.width, flow.height);
}
@ -3080,7 +3080,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
filler->link_max_length = coord_t(scale_(m_support_material_flow.spacing() * link_max_length_factor / support_density));
fill_expolygons_generate_paths(
// Destination
support_layer.support_fills.entities,
support_layer.support_fills.set_entities(),
// Regions to fill
std::move(to_infill),
// Filler and its parameters
@ -3121,7 +3121,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
filler->link_max_length = coord_t(scale_(spacing * link_max_length_factor / density));
fill_expolygons_generate_paths(
// Destination
support_layer.support_fills.entities,
support_layer.support_fills.set_entities(),
// Regions to fill
offset2_ex(raft_layer.polygons, double(SCALED_EPSILON), double(- SCALED_EPSILON)),
// Filler and its parameters
@ -3260,7 +3260,7 @@ void PrintObjectSupportMaterial::generate_toolpaths(
fill_expolygons_generate_paths(
// Destination
layer_ex.extrusions.entities,
layer_ex.extrusions.set_entities(),
// Regions to fill
union_ex(layer_ex.polygons_to_extrude(), true),
// Filler and its parameters
@ -3316,13 +3316,13 @@ void PrintObjectSupportMaterial::generate_toolpaths(
// TODO: use offset2_ex()
to_infill = offset_ex(to_infill, - 0.4f * float(flow.scaled_spacing()));
extrusion_entities_append_paths(
base_layer.extrusions.entities,
base_layer.extrusions.set_entities(),
to_polylines(std::move(to_infill_polygons)),
erSupportMaterial, flow.mm3_per_mm(), flow.width, flow.height);
}
fill_expolygons_generate_paths(
// Destination
base_layer.extrusions.entities,
base_layer.extrusions.set_entities(),
// Regions to fill
std::move(to_infill),
// Filler and its parameters

View File

@ -1623,7 +1623,7 @@ void ExtrusionToVert::use(const ExtrusionPath3D &path3D) { _3DScene::extrusionen
void ExtrusionToVert::use(const ExtrusionMultiPath &multipath) { _3DScene::extrusionentity_to_verts(multipath, print_z, copy, volume); }
void ExtrusionToVert::use(const ExtrusionMultiPath3D &multipath3D) { _3DScene::extrusionentity_to_verts(multipath3D, print_z, copy, volume); }
void ExtrusionToVert::use(const ExtrusionLoop &loop) { _3DScene::extrusionentity_to_verts(loop, print_z, copy, volume); }
void ExtrusionToVert::use(const ExtrusionEntityCollection &collection) { for (const ExtrusionEntity *extrusion_entity : collection.entities) extrusion_entity->visit(*this); }
void ExtrusionToVert::use(const ExtrusionEntityCollection &collection) { for (const ExtrusionEntity *extrusion_entity : collection.entities()) extrusion_entity->visit(*this); }
void _3DScene::extrusionentity_to_verts(const ExtrusionEntity &extrusion_entity, float print_z, const Point &copy, GLVolume &volume)
{

View File

@ -6102,15 +6102,15 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
_3DScene::extrusionentity_to_verts(layerm->perimeters, float(layer->print_z), copy,
volume(idx_layer, layerm->region()->config().perimeter_extruder.value, 0));
if (ctxt.has_infill) {
for (const ExtrusionEntity *ee : layerm->fills.entities) {
for (const ExtrusionEntity *ee : layerm->fills.entities()) {
// fill represents infill extrusions of a single island.
const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
if (fill != nullptr && !fill->entities.empty())
if (fill != nullptr && !fill->entities().empty())
_3DScene::extrusionentity_to_verts(*fill,
float(layer->print_z),
copy,
volume(idx_layer,
is_solid_infill(fill->entities.front()->role()) ?
is_solid_infill(fill->entities().front()->role()) ?
layerm->region()->config().solid_infill_extruder :
layerm->region()->config().infill_extruder,
1));
@ -6120,7 +6120,7 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
if (ctxt.has_support) {
const SupportLayer *support_layer = dynamic_cast<const SupportLayer*>(layer);
if (support_layer) {
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities)
for (const ExtrusionEntity *extrusion_entity : support_layer->support_fills.entities())
if (extrusion_entity != nullptr)
_3DScene::extrusionentity_to_verts(*extrusion_entity, float(layer->print_z), copy,
volume(idx_layer,