Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/libslic3r/SLA/SupportTreeBuilder.hpp')
-rw-r--r--src/libslic3r/SLA/SupportTreeBuilder.hpp230
1 files changed, 91 insertions, 139 deletions
diff --git a/src/libslic3r/SLA/SupportTreeBuilder.hpp b/src/libslic3r/SLA/SupportTreeBuilder.hpp
index 90cf417c8..f29263ca3 100644
--- a/src/libslic3r/SLA/SupportTreeBuilder.hpp
+++ b/src/libslic3r/SLA/SupportTreeBuilder.hpp
@@ -2,7 +2,6 @@
#define SLA_SUPPORTTREEBUILDER_HPP
#include <libslic3r/SLA/Concurrency.hpp>
-#include <libslic3r/SLA/Common.hpp>
#include <libslic3r/SLA/SupportTree.hpp>
#include <libslic3r/SLA/Contour3D.hpp>
#include <libslic3r/SLA/Pad.hpp>
@@ -50,13 +49,6 @@ namespace sla {
* nearby pillar.
*/
-using Coordf = double;
-using Portion = std::tuple<double, double>;
-
-inline Portion make_portion(double a, double b) {
- return std::make_tuple(a, b);
-}
-
template<class Vec> double distance(const Vec& p) {
return std::sqrt(p.transpose() * p);
}
@@ -66,33 +58,25 @@ template<class Vec> double distance(const Vec& pp1, const Vec& pp2) {
return distance(p);
}
-Contour3D sphere(double rho, Portion portion = make_portion(0.0, 2.0*PI),
- double fa=(2*PI/360));
+const Vec3d DOWN = {0.0, 0.0, -1.0};
-// Down facing cylinder in Z direction with arguments:
-// r: radius
-// h: Height
-// ssteps: how many edges will create the base circle
-// sp: starting point
-Contour3D cylinder(double r, double h, size_t ssteps = 45, const Vec3d &sp = {0,0,0});
+struct SupportTreeNode
+{
+ static const constexpr long ID_UNSET = -1;
-const constexpr long ID_UNSET = -1;
+ long id = ID_UNSET; // For identification withing a tree.
+};
-struct Head {
- Contour3D mesh;
-
- size_t steps = 45;
- Vec3d dir = {0, 0, -1};
- Vec3d tr = {0, 0, 0};
+// A pinhead originating from a support point
+struct Head: public SupportTreeNode {
+ Vec3d dir = DOWN;
+ Vec3d pos = {0, 0, 0};
double r_back_mm = 1;
double r_pin_mm = 0.5;
double width_mm = 2;
double penetration_mm = 0.5;
-
- // For identification purposes. This will be used as the index into the
- // container holding the head structures. See SLASupportTree::Impl
- long id = ID_UNSET;
+
// If there is a pillar connecting to this head, then the id will be set.
long pillar_id = ID_UNSET;
@@ -106,31 +90,23 @@ struct Head {
double r_small_mm,
double length_mm,
double penetration,
- const Vec3d &direction = {0, 0, -1}, // direction (normal to the dull end)
- const Vec3d &offset = {0, 0, 0}, // displacement
- const size_t circlesteps = 45);
-
- void transform()
+ const Vec3d &direction = DOWN, // direction (normal to the dull end)
+ const Vec3d &offset = {0, 0, 0} // displacement
+ );
+
+ inline double real_width() const
{
- using Quaternion = Eigen::Quaternion<double>;
-
- // We rotate the head to the specified direction The head's pointing
- // side is facing upwards so this means that it would hold a support
- // point with a normal pointing straight down. This is the reason of
- // the -1 z coordinate
- auto quatern = Quaternion::FromTwoVectors(Vec3d{0, 0, -1}, dir);
-
- for(auto& p : mesh.points) p = quatern * p + tr;
+ return 2 * r_pin_mm + width_mm + 2 * r_back_mm ;
}
-
+
inline double fullwidth() const
{
- return 2 * r_pin_mm + width_mm + 2*r_back_mm - penetration_mm;
+ return real_width() - penetration_mm;
}
inline Vec3d junction_point() const
{
- return tr + ( 2 * r_pin_mm + width_mm + r_back_mm - penetration_mm)*dir;
+ return pos + (fullwidth() - r_back_mm) * dir;
}
inline double request_pillar_radius(double radius) const
@@ -140,31 +116,17 @@ struct Head {
}
};
-struct Junction {
- Contour3D mesh;
+// A junction connecting bridges and pillars
+struct Junction: public SupportTreeNode {
double r = 1;
- size_t steps = 45;
Vec3d pos;
-
- long id = ID_UNSET;
-
- Junction(const Vec3d& tr, double r_mm, size_t stepnum = 45):
- r(r_mm), steps(stepnum), pos(tr)
- {
- mesh = sphere(r_mm, make_portion(0, PI), 2*PI/steps);
- for(auto& p : mesh.points) p += tr;
- }
+
+ Junction(const Vec3d &tr, double r_mm) : r(r_mm), pos(tr) {}
};
-struct Pillar {
- Contour3D mesh;
- Contour3D base;
- double r = 1;
- size_t steps = 0;
+struct Pillar: public SupportTreeNode {
+ double height, r;
Vec3d endpt;
- double height = 0;
-
- long id = ID_UNSET;
// If the pillar connects to a head, this is the id of that head
bool starts_from_head = true; // Could start from a junction as well
@@ -175,54 +137,52 @@ struct Pillar {
// How many pillars are cascaded with this one
unsigned links = 0;
-
- Pillar(const Vec3d& jp, const Vec3d& endp,
- double radius = 1, size_t st = 45);
-
- Pillar(const Junction &junc, const Vec3d &endp)
- : Pillar(junc.pos, endp, junc.r, junc.steps)
- {}
-
- Pillar(const Head &head, const Vec3d &endp, double radius = 1)
- : Pillar(head.junction_point(), endp,
- head.request_pillar_radius(radius), head.steps)
- {}
-
- inline Vec3d startpoint() const
+
+ Pillar(const Vec3d &endp, double h, double radius = 1.):
+ height{h}, r(radius), endpt(endp), starts_from_head(false) {}
+
+ Vec3d startpoint() const
{
- return {endpt(X), endpt(Y), endpt(Z) + height};
+ return {endpt.x(), endpt.y(), endpt.z() + height};
}
- inline const Vec3d& endpoint() const { return endpt; }
-
- Pillar& add_base(double baseheight = 3, double radius = 2);
+ const Vec3d& endpoint() const { return endpt; }
+};
+
+// A base for pillars or bridges that end on the ground
+struct Pedestal: public SupportTreeNode {
+ Vec3d pos;
+ double height, r_bottom, r_top;
+
+ Pedestal(const Vec3d &p, double h, double rbottom, double rtop)
+ : pos{p}, height{h}, r_bottom{rbottom}, r_top{rtop}
+ {}
};
+// This is the thing that anchors a pillar or bridge to the model body.
+// It is actually a reverse pinhead.
+struct Anchor: public Head { using Head::Head; };
+
// A Bridge between two pillars (with junction endpoints)
-struct Bridge {
- Contour3D mesh;
+struct Bridge: public SupportTreeNode {
double r = 0.8;
- long id = ID_UNSET;
Vec3d startp = Vec3d::Zero(), endp = Vec3d::Zero();
Bridge(const Vec3d &j1,
const Vec3d &j2,
- double r_mm = 0.8,
- size_t steps = 45);
+ double r_mm = 0.8): r{r_mm}, startp{j1}, endp{j2}
+ {}
+
+ double get_length() const { return (endp - startp).norm(); }
+ Vec3d get_dir() const { return (endp - startp).normalized(); }
};
-// A bridge that spans from model surface to model surface with small connecting
-// edges on the endpoints. Used for headless support points.
-struct CompactBridge {
- Contour3D mesh;
- long id = ID_UNSET;
-
- CompactBridge(const Vec3d& sp,
- const Vec3d& ep,
- const Vec3d& n,
- double r,
- bool endball = true,
- size_t steps = 45);
+struct DiffBridge: public Bridge {
+ double end_r;
+
+ DiffBridge(const Vec3d &p_s, const Vec3d &p_e, double r_s, double r_e)
+ : Bridge{p_s, p_e, r_s}, end_r{r_e}
+ {}
};
// A wrapper struct around the pad
@@ -258,13 +218,16 @@ struct Pad {
// merged mesh. It can be retrieved using a dedicated method (pad())
class SupportTreeBuilder: public SupportTree {
// For heads it is beneficial to use the same IDs as for the support points.
- std::vector<Head> m_heads;
- std::vector<size_t> m_head_indices;
- std::vector<Pillar> m_pillars;
- std::vector<Junction> m_junctions;
- std::vector<Bridge> m_bridges;
- std::vector<Bridge> m_crossbridges;
- std::vector<CompactBridge> m_compact_bridges;
+ std::vector<Head> m_heads;
+ std::vector<size_t> m_head_indices;
+ std::vector<Pillar> m_pillars;
+ std::vector<Junction> m_junctions;
+ std::vector<Bridge> m_bridges;
+ std::vector<Bridge> m_crossbridges;
+ std::vector<DiffBridge> m_diffbridges;
+ std::vector<Pedestal> m_pedestals;
+ std::vector<Anchor> m_anchors;
+
Pad m_pad;
using Mutex = ccr::SpinningMutex;
@@ -274,8 +237,8 @@ class SupportTreeBuilder: public SupportTree {
mutable bool m_meshcache_valid = false;
mutable double m_model_height = 0; // the full height of the model
- template<class...Args>
- const Bridge& _add_bridge(std::vector<Bridge> &br, Args&&... args)
+ template<class BridgeT, class...Args>
+ const BridgeT& _add_bridge(std::vector<BridgeT> &br, Args&&... args)
{
std::lock_guard<Mutex> lk(m_mutex);
br.emplace_back(std::forward<Args>(args)...);
@@ -306,7 +269,7 @@ public:
return m_heads.back();
}
- template<class...Args> long add_pillar(long headid, Args&&... args)
+ template<class...Args> long add_pillar(long headid, double length)
{
std::lock_guard<Mutex> lk(m_mutex);
if (m_pillars.capacity() < m_heads.size())
@@ -315,7 +278,9 @@ public:
assert(headid >= 0 && size_t(headid) < m_head_indices.size());
Head &head = m_heads[m_head_indices[size_t(headid)]];
- m_pillars.emplace_back(head, std::forward<Args>(args)...);
+ Vec3d hjp = head.junction_point() - Vec3d{0, 0, length};
+ m_pillars.emplace_back(hjp, length, head.r_back_mm);
+
Pillar& pillar = m_pillars.back();
pillar.id = long(m_pillars.size() - 1);
head.pillar_id = pillar.id;
@@ -326,11 +291,15 @@ public:
return pillar.id;
}
- void add_pillar_base(long pid, double baseheight = 3, double radius = 2)
+ void add_pillar_base(long pid, double baseheight = 3, double radius = 2);
+
+ template<class...Args> const Anchor& add_anchor(Args&&...args)
{
std::lock_guard<Mutex> lk(m_mutex);
- assert(pid >= 0 && size_t(pid) < m_pillars.size());
- m_pillars[size_t(pid)].add_base(baseheight, radius);
+ m_anchors.emplace_back(std::forward<Args>(args)...);
+ m_anchors.back().id = long(m_junctions.size() - 1);
+ m_meshcache_valid = false;
+ return m_anchors.back();
}
void increment_bridges(const Pillar& pillar)
@@ -371,17 +340,6 @@ public:
return pillar.id;
}
- const Pillar& head_pillar(unsigned headid) const
- {
- std::lock_guard<Mutex> lk(m_mutex);
- assert(headid < m_head_indices.size());
-
- const Head& h = m_heads[m_head_indices[headid]];
- assert(h.pillar_id >= 0 && h.pillar_id < long(m_pillars.size()));
-
- return m_pillars[size_t(h.pillar_id)];
- }
-
template<class...Args> const Junction& add_junction(Args&&... args)
{
std::lock_guard<Mutex> lk(m_mutex);
@@ -391,18 +349,18 @@ public:
return m_junctions.back();
}
- const Bridge& add_bridge(const Vec3d &s, const Vec3d &e, double r, size_t n = 45)
+ const Bridge& add_bridge(const Vec3d &s, const Vec3d &e, double r)
{
- return _add_bridge(m_bridges, s, e, r, n);
+ return _add_bridge(m_bridges, s, e, r);
}
- const Bridge& add_bridge(long headid, const Vec3d &endp, size_t s = 45)
+ const Bridge& add_bridge(long headid, const Vec3d &endp)
{
std::lock_guard<Mutex> lk(m_mutex);
assert(headid >= 0 && size_t(headid) < m_head_indices.size());
Head &h = m_heads[m_head_indices[size_t(headid)]];
- m_bridges.emplace_back(h.junction_point(), endp, h.r_back_mm, s);
+ m_bridges.emplace_back(h.junction_point(), endp, h.r_back_mm);
m_bridges.back().id = long(m_bridges.size() - 1);
h.bridge_id = m_bridges.back().id;
@@ -414,14 +372,10 @@ public:
{
return _add_bridge(m_crossbridges, std::forward<Args>(args)...);
}
-
- template<class...Args> const CompactBridge& add_compact_bridge(Args&&...args)
+
+ template<class...Args> const DiffBridge& add_diffbridge(Args&&... args)
{
- std::lock_guard<Mutex> lk(m_mutex);
- m_compact_bridges.emplace_back(std::forward<Args>(args)...);
- m_compact_bridges.back().id = long(m_compact_bridges.size() - 1);
- m_meshcache_valid = false;
- return m_compact_bridges.back();
+ return _add_bridge(m_diffbridges, std::forward<Args>(args)...);
}
Head &head(unsigned id)
@@ -439,7 +393,7 @@ public:
}
inline const std::vector<Pillar> &pillars() const { return m_pillars; }
- inline const std::vector<Head> &heads() const { return m_heads; }
+ inline const std::vector<Head> &heads() const { return m_heads; }
inline const std::vector<Bridge> &bridges() const { return m_bridges; }
inline const std::vector<Bridge> &crossbridges() const { return m_crossbridges; }
@@ -464,7 +418,7 @@ public:
const Pad& pad() const { return m_pad; }
// WITHOUT THE PAD!!!
- const TriangleMesh &merged_mesh() const;
+ const TriangleMesh &merged_mesh(size_t steps = 45) const;
// WITH THE PAD
double full_height() const;
@@ -488,8 +442,6 @@ public:
virtual const TriangleMesh &retrieve_mesh(
MeshType meshtype = MeshType::Support) const override;
-
- bool build(const SupportableMesh &supportable_mesh);
};
}} // namespace Slic3r::sla