mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-16 14:21:50 +08:00
cherry-picked slic3r/Slic3r#4809
changed the ExtrusionEntity visitor a bit and add new ones.
This commit is contained in:
parent
00dd5c82bc
commit
3aea01e815
@ -9,6 +9,21 @@
|
||||
#include <sstream>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
//// extrusion entity visitor
|
||||
void ExtrusionVisitor::use(ExtrusionPath &path) { default_use(path); };
|
||||
void ExtrusionVisitor::use(ExtrusionPath3D &path3D) { default_use(path3D); }
|
||||
void ExtrusionVisitor::use(ExtrusionMultiPath &multipath) { default_use(multipath); }
|
||||
void ExtrusionVisitor::use(ExtrusionMultiPath3D &multipath3D) { default_use(multipath3D); }
|
||||
void ExtrusionVisitor::use(ExtrusionLoop &loop) { default_use(loop); }
|
||||
void ExtrusionVisitor::use(ExtrusionEntityCollection &collection) { default_use(collection); }
|
||||
|
||||
void ExtrusionVisitorConst::use(const ExtrusionPath &path) { default_use(path); }
|
||||
void ExtrusionVisitorConst::use(const ExtrusionPath3D &path3D) { default_use(path3D); }
|
||||
void ExtrusionVisitorConst::use(const ExtrusionMultiPath &multipath) { default_use(multipath); }
|
||||
void ExtrusionVisitorConst::use(const ExtrusionMultiPath3D &multipath3D) { default_use(multipath3D); }
|
||||
void ExtrusionVisitorConst::use(const ExtrusionLoop &loop) { default_use(loop); }
|
||||
void ExtrusionVisitorConst::use(const ExtrusionEntityCollection &collection) { default_use(collection); }
|
||||
|
||||
void
|
||||
ExtrusionPath::intersect_expolygons(const ExPolygonCollection &collection, ExtrusionEntityCollection* retval) const
|
||||
@ -299,24 +314,24 @@ void ExtrusionPrinter::use(const ExtrusionEntityCollection &collection) {
|
||||
}
|
||||
|
||||
|
||||
class ExtrusionTreeVisitor : ExtrusionVisitor {
|
||||
public:
|
||||
//virtual void use(ExtrusionEntity &entity) { assert(false); };
|
||||
virtual void use(ExtrusionPath &path) override { const ExtrusionPath &constpath = path; use(constpath); };
|
||||
virtual void use(ExtrusionPath3D &path3D) override { const ExtrusionPath3D &constpath3D = path3D; use(constpath3D); };
|
||||
virtual void use(ExtrusionMultiPath &multipath) override { const ExtrusionMultiPath &constmultipath = multipath; use(constmultipath); };
|
||||
virtual void use(ExtrusionMultiPath3D &multipath3D) override { const ExtrusionMultiPath3D &constmultipath3D = multipath3D; use(constmultipath3D); };
|
||||
virtual void use(ExtrusionLoop &loop) override { const ExtrusionLoop &constloop = loop; use(constloop); };
|
||||
virtual void use(ExtrusionEntityCollection &collection) { const ExtrusionEntityCollection &constcollection = collection; use(constcollection); };
|
||||
virtual void use(const ExtrusionPath &path) override { assert(false); };
|
||||
virtual void use(const ExtrusionPath3D &path3D) override { assert(false); };
|
||||
virtual void use(const ExtrusionMultiPath &multipath) override { assert(false); };
|
||||
virtual void use(const ExtrusionMultiPath3D &multipath3D) { assert(false); };
|
||||
virtual void use(const ExtrusionLoop &loop) override { assert(false); };
|
||||
virtual void use(const ExtrusionEntityCollection &collection) { assert(false); };
|
||||
virtual void use_default(ExtrusionEntity &entity) { const ExtrusionEntity &constentity = entity; use_default(constentity); };
|
||||
virtual void use_default(const ExtrusionEntity &entity) {};
|
||||
|
||||
};
|
||||
//class ExtrusionTreeVisitor : ExtrusionVisitor {
|
||||
//public:
|
||||
// //virtual void use(ExtrusionEntity &entity) { assert(false); };
|
||||
// virtual void use(ExtrusionPath &path) override { const ExtrusionPath &constpath = path; use(constpath); };
|
||||
// virtual void use(ExtrusionPath3D &path3D) override { const ExtrusionPath3D &constpath3D = path3D; use(constpath3D); };
|
||||
// virtual void use(ExtrusionMultiPath &multipath) override { const ExtrusionMultiPath &constmultipath = multipath; use(constmultipath); };
|
||||
// virtual void use(ExtrusionMultiPath3D &multipath3D) override { const ExtrusionMultiPath3D &constmultipath3D = multipath3D; use(constmultipath3D); };
|
||||
// virtual void use(ExtrusionLoop &loop) override { const ExtrusionLoop &constloop = loop; use(constloop); };
|
||||
// virtual void use(ExtrusionEntityCollection &collection) { const ExtrusionEntityCollection &constcollection = collection; use(constcollection); };
|
||||
// virtual void use(const ExtrusionPath &path) override { assert(false); };
|
||||
// virtual void use(const ExtrusionPath3D &path3D) override { assert(false); };
|
||||
// virtual void use(const ExtrusionMultiPath &multipath) override { assert(false); };
|
||||
// virtual void use(const ExtrusionMultiPath3D &multipath3D) { assert(false); };
|
||||
// virtual void use(const ExtrusionLoop &loop) override { assert(false); };
|
||||
// virtual void use(const ExtrusionEntityCollection &collection) { assert(false); };
|
||||
// virtual void use_default(ExtrusionEntity &entity) { const ExtrusionEntity &constentity = entity; use_default(constentity); };
|
||||
// virtual void use_default(const ExtrusionEntity &entity) {};
|
||||
//
|
||||
//};
|
||||
|
||||
}
|
||||
|
@ -69,27 +69,53 @@ enum ExtrusionLoopRole {
|
||||
};
|
||||
|
||||
|
||||
class ExtrusionEntity;
|
||||
class ExtrusionPath;
|
||||
class ExtrusionPath3D;
|
||||
class ExtrusionMultiPath;
|
||||
class ExtrusionMultiPath3D;
|
||||
class ExtrusionLoop;
|
||||
//
|
||||
//class ExtrusionVisitor {
|
||||
//public:
|
||||
// virtual void default_use(ExtrusionEntity &entity) { assert(false); };
|
||||
// virtual void use(ExtrusionPath &path) { ExtrusionEntity &entity = path; default_use(entity); };
|
||||
// virtual void use(ExtrusionPath3D &path3D) { ExtrusionPath &path = path3D; use(path); };
|
||||
// virtual void use(ExtrusionMultiPath &multipath) { ExtrusionEntity &entity = multipath; default_use(entity); };
|
||||
// virtual void use(ExtrusionMultiPath3D &multipath3D) { ExtrusionEntity &entity = multipath3D; default_use(entity); };
|
||||
// virtual void use(ExtrusionLoop &loop) { ExtrusionEntity &entity = loop; default_use(entity); };
|
||||
// virtual void use(ExtrusionEntityCollection &collection) { ExtrusionEntity &entity = collection; default_use(entity); };
|
||||
//};
|
||||
//class ExtrusionVisitorConst {
|
||||
//public:
|
||||
// virtual void default_use(const ExtrusionEntity &entity) { assert(false); };
|
||||
// virtual void use(const ExtrusionPath &path) { const ExtrusionEntity &entity = path; default_use(entity); };
|
||||
// virtual void use(const ExtrusionPath3D &path3D) { const ExtrusionPath &path = path3D; use(path); };
|
||||
// virtual void use(const ExtrusionMultiPath &multipath) { const ExtrusionEntity &entity = multipath; default_use(entity); };
|
||||
// virtual void use(const ExtrusionMultiPath3D &multipath3D) { const ExtrusionEntity &entity = multipath3D; default_use(entity); };
|
||||
// virtual void use(const ExtrusionLoop &loop) { const ExtrusionEntity &entity = loop; default_use(entity); };
|
||||
// virtual void use(const ExtrusionEntityCollection &collection) { const ExtrusionEntity &entity = collection; default_use(entity); };
|
||||
//};
|
||||
|
||||
class ExtrusionVisitor {
|
||||
public:
|
||||
//virtual void use(ExtrusionEntity &entity) { assert(false); };
|
||||
virtual void use(ExtrusionPath &path) { const ExtrusionPath &constpath = path; use(constpath); };
|
||||
virtual void use(ExtrusionPath3D &path3D) { const ExtrusionPath3D &constpath3D = path3D; use(constpath3D); };
|
||||
virtual void use(ExtrusionMultiPath &multipath) { const ExtrusionMultiPath &constmultipath = multipath; use(constmultipath); };
|
||||
virtual void use(ExtrusionMultiPath3D &multipath3D) { const ExtrusionMultiPath3D &constmultipath3D = multipath3D; use(constmultipath3D); };
|
||||
virtual void use(ExtrusionLoop &loop) { const ExtrusionLoop &constloop = loop; use(constloop); };
|
||||
virtual void use(ExtrusionEntityCollection &collection) { const ExtrusionEntityCollection &constcollection = collection; use(constcollection); };
|
||||
virtual void use(const ExtrusionPath &path) { assert(false); };
|
||||
virtual void use(const ExtrusionPath3D &path3D) { assert(false); };
|
||||
virtual void use(const ExtrusionMultiPath &multipath) { assert(false); };
|
||||
virtual void use(const ExtrusionMultiPath3D &multipath3D) { assert(false); };
|
||||
virtual void use(const ExtrusionLoop &loop) { assert(false); };
|
||||
virtual void use(const ExtrusionEntityCollection &collection) { assert(false); };
|
||||
|
||||
virtual void default_use(ExtrusionEntity &entity) { assert(false); };
|
||||
virtual void use(ExtrusionPath &path);
|
||||
virtual void use(ExtrusionPath3D &path3D);
|
||||
virtual void use(ExtrusionMultiPath &multipath);
|
||||
virtual void use(ExtrusionMultiPath3D &multipath3D);
|
||||
virtual void use(ExtrusionLoop &loop);
|
||||
virtual void use(ExtrusionEntityCollection &collection);
|
||||
};
|
||||
class ExtrusionVisitorConst {
|
||||
public:
|
||||
virtual void default_use(const ExtrusionEntity &entity) { assert(false); };
|
||||
virtual void use(const ExtrusionPath &path);
|
||||
virtual void use(const ExtrusionPath3D &path3D);
|
||||
virtual void use(const ExtrusionMultiPath &multipath);
|
||||
virtual void use(const ExtrusionMultiPath3D &multipath3D);
|
||||
virtual void use(const ExtrusionLoop &loop);
|
||||
virtual void use(const ExtrusionEntityCollection &collection);
|
||||
};
|
||||
|
||||
class ExtrusionEntity
|
||||
@ -123,7 +149,7 @@ public:
|
||||
virtual double length() const = 0;
|
||||
virtual double total_volume() const = 0;
|
||||
virtual void visit(ExtrusionVisitor &visitor) = 0;
|
||||
virtual void visit(ExtrusionVisitor &visitor) const = 0;
|
||||
virtual void visit(ExtrusionVisitorConst &visitor) const = 0;
|
||||
};
|
||||
|
||||
typedef std::vector<ExtrusionEntity*> ExtrusionEntitiesPtr;
|
||||
@ -185,7 +211,7 @@ public:
|
||||
void collect_polylines(Polylines &dst) const override { if (! this->polyline.empty()) dst.emplace_back(this->polyline); }
|
||||
double total_volume() const override { return mm3_per_mm * unscale<double>(length()); }
|
||||
virtual void visit(ExtrusionVisitor &visitor) override { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitor &visitor) const override { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitorConst &visitor) const override { visitor.use(*this); };
|
||||
|
||||
protected:
|
||||
void _inflate_collection(const Polylines &polylines, ExtrusionEntityCollection* collection) const;
|
||||
@ -214,7 +240,7 @@ public:
|
||||
}
|
||||
ExtrusionPath3D* clone() const { return new ExtrusionPath3D(*this); }
|
||||
virtual void visit(ExtrusionVisitor &visitor) override { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitor &visitor) const override { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitorConst &visitor) const override { visitor.use(*this); };
|
||||
|
||||
void push_back(Point p, coord_t z_offset) { polyline.points.push_back(p); z_offsets.push_back(z_offset); }
|
||||
|
||||
@ -320,7 +346,7 @@ public:
|
||||
virtual ExtrusionMultiPath* clone() const override { return new ExtrusionMultiPath(*this); }
|
||||
|
||||
virtual void visit(ExtrusionVisitor &visitor) override { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitor &visitor) const override { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitorConst &visitor) const override { visitor.use(*this); };
|
||||
};
|
||||
// Single continuous extrusion path, possibly with varying extrusion thickness, extrusion height or bridging / non bridging.
|
||||
class ExtrusionMultiPath3D : public ExtrusionMultiEntity<ExtrusionPath3D> {
|
||||
@ -335,7 +361,7 @@ public:
|
||||
virtual ExtrusionMultiPath3D* clone() const override { return new ExtrusionMultiPath3D(*this); }
|
||||
|
||||
virtual void visit(ExtrusionVisitor &visitor) override { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitor &visitor) const override { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitorConst &visitor) const override { visitor.use(*this); };
|
||||
|
||||
virtual bool can_reverse() const override { return false; }
|
||||
virtual void reverse() override {
|
||||
@ -391,7 +417,7 @@ public:
|
||||
void collect_polylines(Polylines &dst) const override { Polyline pl = this->as_polyline(); if (! pl.empty()) dst.emplace_back(std::move(pl)); }
|
||||
double total_volume() const override { double volume = 0.; for (const auto& path : paths) volume += path.total_volume(); return volume; }
|
||||
virtual void visit(ExtrusionVisitor &visitor) override { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitor &visitor) const override { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitorConst &visitor) const override { visitor.use(*this); };
|
||||
|
||||
private:
|
||||
ExtrusionLoopRole m_loop_role;
|
||||
@ -482,7 +508,7 @@ inline void extrusion_entities_append_loops(ExtrusionEntitiesPtr &dst, Polygons
|
||||
loops.clear();
|
||||
}
|
||||
|
||||
class ExtrusionPrinter : public ExtrusionVisitor {
|
||||
class ExtrusionPrinter : public ExtrusionVisitorConst {
|
||||
std::stringstream ss;
|
||||
public:
|
||||
virtual void use(const ExtrusionPath &path);
|
||||
@ -492,7 +518,10 @@ public:
|
||||
virtual void use(const ExtrusionLoop &loop);
|
||||
virtual void use(const ExtrusionEntityCollection &collection);
|
||||
std::string str() { return ss.str(); }
|
||||
// void clear() { return ss.clear(); }
|
||||
std::string && print(ExtrusionEntity &entity) && {
|
||||
entity.visit(*this);
|
||||
return std::move(ss.str());
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -174,78 +174,73 @@ void ExtrusionEntityCollection::polygons_covered_by_spacing(Polygons &out, const
|
||||
size_t
|
||||
ExtrusionEntityCollection::items_count() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
|
||||
if ((*it)->is_collection()) {
|
||||
ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
|
||||
count += collection->items_count();
|
||||
} else {
|
||||
++count;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
return CountEntities().count(*this);
|
||||
}
|
||||
|
||||
/* Returns a single vector of pointers to all non-collection items contained in this one */
|
||||
void
|
||||
ExtrusionEntityCollection::flatten(ExtrusionEntityCollection* retval) const
|
||||
CountEntities::use(const ExtrusionEntityCollection &coll) {
|
||||
for (const ExtrusionEntity* entity : coll.entities) {
|
||||
entity->visit(*this);
|
||||
}
|
||||
}
|
||||
//
|
||||
//void
|
||||
//ExtrusionEntityCollection::flatten(ExtrusionEntityCollection* retval, bool preserve_ordering) const
|
||||
//{
|
||||
// if (this->no_sort && preserve_ordering) {
|
||||
// /// if we want to preserve ordering and we can't sort, break out the unsorted ones first.
|
||||
// ExtrusionEntityCollection *unsortable = new ExtrusionEntityCollection();
|
||||
// unsortable->no_sort = true;
|
||||
// unsortable->orig_indices = this->orig_indices;
|
||||
// retval->append(*unsortable);
|
||||
// for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
|
||||
// if ((*it)->is_collection()) {
|
||||
// ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
|
||||
// collection->flatten(unsortable, preserve_ordering);
|
||||
// } else {
|
||||
// unsortable->append(**it);
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
|
||||
// if ((*it)->is_collection()) {
|
||||
// ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
|
||||
// retval->append(collection->flatten().entities);
|
||||
// } else {
|
||||
// retval->append(**it);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
/* Returns a single vector of chained (new) pointers to all non-collection items contained in this one */
|
||||
ExtrusionEntityCollection
|
||||
ExtrusionEntityCollection::flatten(bool preserve_ordering) const
|
||||
{
|
||||
for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
|
||||
if ((*it)->is_collection()) {
|
||||
ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
|
||||
retval->append(collection->flatten().entities);
|
||||
} else {
|
||||
retval->append(**it);
|
||||
//ExtrusionEntityCollection coll;
|
||||
//this->flatten(&coll, preserve_ordering);
|
||||
//return coll;
|
||||
return FlatenEntities(preserve_ordering).flatten(*this);
|
||||
|
||||
}
|
||||
void
|
||||
FlatenEntities::use(const ExtrusionEntityCollection &coll) {
|
||||
if (coll.no_sort && preserve_ordering) {
|
||||
to_fill.append(FlatenEntities(coll, preserve_ordering).flatten(coll));
|
||||
} else {
|
||||
for (const ExtrusionEntity* entity : coll.entities) {
|
||||
entity->visit(*this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExtrusionEntityCollection
|
||||
ExtrusionEntityCollection::flatten() const
|
||||
{
|
||||
ExtrusionEntityCollection coll;
|
||||
this->flatten(&coll);
|
||||
return coll;
|
||||
ExtrusionEntityCollection&&
|
||||
FlatenEntities::flatten(const ExtrusionEntityCollection &to_flatten) && {
|
||||
for (const ExtrusionEntity* entity : to_flatten.entities) {
|
||||
entity->visit(*this);
|
||||
}
|
||||
return std::move(to_fill);
|
||||
}
|
||||
|
||||
/* Returns a vector of chained (new) pointers to all non-collection items contained in this one */
|
||||
void
|
||||
ExtrusionEntityCollection::flattenIfSortable(ExtrusionEntityCollection* retval) const
|
||||
{
|
||||
if (no_sort){
|
||||
ExtrusionEntityCollection *unsortable = new ExtrusionEntityCollection(*this);
|
||||
retval->append(*unsortable);
|
||||
unsortable->entities.clear();
|
||||
for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
|
||||
if ((*it)->is_collection()) {
|
||||
ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
|
||||
collection->flattenIfSortable(unsortable);
|
||||
}
|
||||
else {
|
||||
unsortable->append(**it);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for (ExtrusionEntitiesPtr::const_iterator it = this->entities.begin(); it != this->entities.end(); ++it) {
|
||||
if ((*it)->is_collection()) {
|
||||
ExtrusionEntityCollection* collection = dynamic_cast<ExtrusionEntityCollection*>(*it);
|
||||
retval->append(collection->flattenIfSortable().entities);
|
||||
}
|
||||
else {
|
||||
retval->append(**it);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExtrusionEntityCollection
|
||||
ExtrusionEntityCollection::flattenIfSortable() const
|
||||
{
|
||||
ExtrusionEntityCollection coll;
|
||||
this->flattenIfSortable(&coll);
|
||||
return coll;
|
||||
}
|
||||
|
||||
double
|
||||
ExtrusionEntityCollection::min_mm3_per_mm() const
|
||||
|
@ -10,9 +10,14 @@ class ExtrusionEntityCollection : public ExtrusionEntity
|
||||
{
|
||||
public:
|
||||
ExtrusionEntityCollection* clone() const;
|
||||
|
||||
/// 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
|
||||
|
||||
std::vector<size_t> orig_indices; // handy for XS
|
||||
bool no_sort;
|
||||
|
||||
ExtrusionEntityCollection(): no_sort(false) {};
|
||||
ExtrusionEntityCollection(const ExtrusionEntityCollection &other) : orig_indices(other.orig_indices), no_sort(other.no_sort) { this->append(other.entities); }
|
||||
ExtrusionEntityCollection(ExtrusionEntityCollection &&other) : entities(std::move(other.entities)), orig_indices(std::move(other.orig_indices)), no_sort(other.no_sort) {}
|
||||
@ -21,6 +26,8 @@ public:
|
||||
ExtrusionEntityCollection& operator=(ExtrusionEntityCollection &&other)
|
||||
{ this->entities = std::move(other.entities); this->orig_indices = std::move(other.orig_indices); this->no_sort = other.no_sort; return *this; }
|
||||
~ExtrusionEntityCollection() { clear(); }
|
||||
|
||||
/// Operator to convert and flatten this collection to a single vector of ExtrusionPaths.
|
||||
explicit operator ExtrusionPaths() const;
|
||||
|
||||
bool is_collection() const { return true; };
|
||||
@ -80,11 +87,20 @@ public:
|
||||
{ Polygons out; this->polygons_covered_by_width(out, scaled_epsilon); return out; }
|
||||
Polygons polygons_covered_by_spacing(const float scaled_epsilon = 0.f) const
|
||||
{ Polygons out; this->polygons_covered_by_spacing(out, scaled_epsilon); return out; }
|
||||
|
||||
/// Recursively count paths and loops contained in this collection
|
||||
size_t items_count() const;
|
||||
void flatten(ExtrusionEntityCollection* retval) const;
|
||||
ExtrusionEntityCollection flatten() const;
|
||||
void flattenIfSortable(ExtrusionEntityCollection* retval) const;
|
||||
ExtrusionEntityCollection flattenIfSortable() const;
|
||||
|
||||
/// Returns a single vector of pointers to all non-collection items contained in this one
|
||||
/// \param retval a pointer to the output memory space.
|
||||
/// \param preserve_ordering Flag to method that will flatten if and only if the underlying collection is sortable when True (default: False).
|
||||
void flatten(ExtrusionEntityCollection* retval, bool preserve_ordering = false) 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).
|
||||
/// \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 min_mm3_per_mm() const;
|
||||
double total_volume() const override { double volume=0.; for (const auto& ent : entities) volume+=ent->total_volume(); return volume; }
|
||||
|
||||
@ -104,7 +120,34 @@ public:
|
||||
return 0.;
|
||||
}
|
||||
virtual void visit(ExtrusionVisitor &visitor) { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitor &visitor) const { visitor.use(*this); };
|
||||
virtual void visit(ExtrusionVisitorConst &visitor) const { visitor.use(*this); };
|
||||
};
|
||||
|
||||
//// visitors /////
|
||||
|
||||
class CountEntities : public ExtrusionVisitorConst {
|
||||
public:
|
||||
size_t count(const ExtrusionEntity &coll) { coll.visit(*this); return leaf_number; }
|
||||
size_t leaf_number = 0;
|
||||
virtual void default_use(const ExtrusionEntity &entity) override { ++leaf_number; }
|
||||
virtual void use(const ExtrusionEntityCollection &coll) override;
|
||||
};
|
||||
|
||||
class FlatenEntities : public ExtrusionVisitorConst {
|
||||
ExtrusionEntityCollection to_fill;
|
||||
bool preserve_ordering;
|
||||
public:
|
||||
FlatenEntities(bool preserve_ordering) : preserve_ordering(preserve_ordering) {}
|
||||
FlatenEntities(ExtrusionEntityCollection pattern, bool preserve_ordering) : preserve_ordering(preserve_ordering) {
|
||||
to_fill.no_sort = pattern.no_sort;
|
||||
to_fill.orig_indices = pattern.orig_indices;
|
||||
}
|
||||
ExtrusionEntityCollection get() {
|
||||
return to_fill;
|
||||
};
|
||||
ExtrusionEntityCollection&& flatten(const ExtrusionEntityCollection &to_flatten) &&;
|
||||
virtual void default_use(const ExtrusionEntity &entity) override { to_fill.append(entity); }
|
||||
virtual void use(const ExtrusionEntityCollection &coll) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -221,6 +221,7 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
|
||||
else if (!is_bridge)
|
||||
fill_pattern = layerm.region()->config().solid_fill_pattern.value;
|
||||
} else {
|
||||
|
||||
if (layerm.region()->config().infill_dense.getBool()
|
||||
&& layerm.region()->config().fill_density<40
|
||||
&& surface.maxNbSolidLayersOnTop <= 1
|
||||
|
@ -1420,7 +1420,8 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
|
||||
for (Polylines::iterator it = polylines_out.begin() + n_polylines_out_initial; it != polylines_out.end(); ++ it) {
|
||||
// No need to translate, the absolute position is irrelevant.
|
||||
// it->translate(- rotate_vector.second(0), - rotate_vector.second(1));
|
||||
assert(! it->has_duplicate_points());
|
||||
//assert(! it->has_duplicate_points());
|
||||
it->remove_duplicate_points();
|
||||
it->rotate(rotate_vector.first);
|
||||
//FIXME rather simplify the paths to avoid very short edges?
|
||||
//assert(! it->has_duplicate_points());
|
||||
@ -1750,14 +1751,12 @@ FillRectilinearSawtooth::fill_surface_extrusion(const Surface *surface, const Fi
|
||||
idx++;
|
||||
}
|
||||
if (current_extrusion->size() < 2) extrusions->paths.pop_back();
|
||||
ExtrusionPrinter print; extrusions->visit(print);
|
||||
if (!extrusions->paths.empty()) eec->entities.push_back(extrusions);
|
||||
else delete extrusions;
|
||||
}
|
||||
// === end ===
|
||||
if (!eec->empty()) {
|
||||
out.push_back(eec);
|
||||
ExtrusionPrinter print; eec->visit(print);
|
||||
} else {
|
||||
delete eec;
|
||||
}
|
||||
|
@ -2547,7 +2547,7 @@ void GCode::_write(FILE* file, const char *what)
|
||||
|
||||
//const char * gcode_pp = _post_process(what).c_str();
|
||||
std::string str_preproc{ what };
|
||||
_post_process(str_preproc);
|
||||
//_post_process(str_preproc);
|
||||
|
||||
const std::string str_ana = m_analyzer.process_gcode(str_preproc);
|
||||
|
||||
@ -3030,8 +3030,8 @@ void GCode::ObjectByExtruder::Island::Region::append(const std::string& type, co
|
||||
|
||||
|
||||
// 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 flattenIfSortable()
|
||||
ExtrusionEntitiesPtr entities = eec->flattenIfSortable().entities;
|
||||
//don't do fill->entities because it will discard no_sort, we must use flatten(preserve_ordering = true)
|
||||
ExtrusionEntitiesPtr entities = eec->flatten(true).entities;
|
||||
perimeters_or_infills->append(entities);
|
||||
|
||||
for (unsigned int i = 0; i<entities.size(); ++i)
|
||||
|
@ -126,7 +126,7 @@ private:
|
||||
bool i_have_brim = false;
|
||||
};
|
||||
|
||||
class GCode : ExtrusionVisitor {
|
||||
class GCode : ExtrusionVisitorConst {
|
||||
public:
|
||||
GCode() :
|
||||
m_origin(Vec2d::Zero()),
|
||||
|
@ -2709,6 +2709,7 @@ void modulate_extrusion_by_overlapping_layers(
|
||||
// The extrusions do not overlap with any other extrusion.
|
||||
return;
|
||||
|
||||
//TODO: should preserve the unsortable things
|
||||
ExtrusionEntityCollection flatten_extrusions_in_out = extrusions_in_out.flatten();
|
||||
|
||||
// Get the initial extrusion parameters.
|
||||
|
@ -1670,8 +1670,7 @@ void ExtrusionToVert::use(const ExtrusionEntityCollection &collection) { for (co
|
||||
|
||||
void _3DScene::extrusionentity_to_verts(const ExtrusionEntity &extrusion_entity, float print_z, const Point ©, GLVolume &volume)
|
||||
{
|
||||
ExtrusionToVert visitor(print_z, copy, volume);
|
||||
extrusion_entity.visit(visitor);
|
||||
extrusion_entity.visit(ExtrusionToVert(print_z, copy, volume));
|
||||
}
|
||||
|
||||
void _3DScene::polyline3_to_verts(const Polyline3& polyline, double width, double height, GLVolume& volume)
|
||||
|
@ -622,7 +622,7 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class ExtrusionToVert : public ExtrusionVisitor {
|
||||
class ExtrusionToVert : public ExtrusionVisitorConst {
|
||||
float print_z;
|
||||
const Point ©
|
||||
GLVolume &volume;
|
||||
|
@ -4618,13 +4618,14 @@ void GLCanvas3D::_load_print_object_toolpaths(const PrintObject& print_object, c
|
||||
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->entities.empty())
|
||||
if (fill != nullptr)
|
||||
_3DScene::extrusionentity_to_verts(*fill, float(layer->print_z), copy,
|
||||
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()) ?
|
||||
layerm->region()->config().solid_infill_extruder :
|
||||
layerm->region()->config().infill_extruder,
|
||||
is_solid_infill(fill->entities.front()->role()) ?
|
||||
layerm->region()->config().solid_infill_extruder :
|
||||
layerm->region()->config().infill_extruder,
|
||||
1));
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ set(SLIC3R_TEST_SOURCES
|
||||
libslic3r/test_print.cpp
|
||||
libslic3r/test_thin.cpp
|
||||
libslic3r/test_denserinfill.cpp
|
||||
libslic3r/test_extrusion_entity.cpp
|
||||
)
|
||||
|
||||
if (NOT TARGET Catch)
|
||||
|
@ -1,4 +1,6 @@
|
||||
|
||||
#define CATCH_CONFIG_DISABLE
|
||||
|
||||
#include <catch.hpp>
|
||||
#include "../test_data.hpp"
|
||||
#include "../../libslic3r/libslic3r.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user