Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::sla::BranchingTreeBuilder Class Reference
+ Inheritance diagram for Slic3r::sla::BranchingTreeBuilder:
+ Collaboration diagram for Slic3r::sla::BranchingTreeBuilder:

Public Member Functions

 BranchingTreeBuilder (SupportTreeBuilder &builder, const SupportableMesh &sm, const branchingtree::PointCloud &cloud)
 
bool add_bridge (const branchingtree::Node &from, const branchingtree::Node &to) override
 
bool add_merger (const branchingtree::Node &node, const branchingtree::Node &closest, const branchingtree::Node &merge_node) override
 
bool add_ground_bridge (const branchingtree::Node &from, const branchingtree::Node &) override
 
bool add_mesh_bridge (const branchingtree::Node &from, const branchingtree::Node &to) override
 
std::optional< Vec3fsuggest_avoidance (const branchingtree::Node &from, float max_bridge_len) const override
 
void report_unroutable (const branchingtree::Node &j) override
 
const std::vector< size_t > & unroutable_pinheads () const
 
bool is_valid () const override
 
const std::vector< branchingtree::Node > & pillars () const
 
const GroundConnectionground_conn (size_t pillar) const
 

Private Member Functions

double get_radius (const branchingtree::Node &j) const
 
void build_subtree (size_t root)
 
void discard_subtree (size_t root)
 
void discard_subtree_rescure (size_t root)
 

Private Attributes

SupportTreeBuilderm_builder
 
const SupportableMeshm_sm
 
const branchingtree::PointCloudm_cloud
 
std::vector< branchingtree::Nodem_pillars
 
std::map< int, GroundConnectionm_gnd_connections
 
execution::SpinningMutex< ExecutionTBBm_gnd_connections_mtx
 
std::vector< size_t > m_unroutable_pinheads
 

Static Private Attributes

static constexpr double WIDENING_SCALE = 0.05
 

Detailed Description

Constructor & Destructor Documentation

◆ BranchingTreeBuilder()

Slic3r::sla::BranchingTreeBuilder::BranchingTreeBuilder ( SupportTreeBuilder builder,
const SupportableMesh sm,
const branchingtree::PointCloud cloud 
)
inline
131 : m_builder{builder}, m_sm{sm}, m_cloud{cloud}
132 {}
const SupportableMesh & m_sm
Definition BranchingTreeSLA.cpp:20
SupportTreeBuilder & m_builder
Definition BranchingTreeSLA.cpp:19
const branchingtree::PointCloud & m_cloud
Definition BranchingTreeSLA.cpp:21

Member Function Documentation

◆ add_bridge()

bool Slic3r::sla::BranchingTreeBuilder::add_bridge ( const branchingtree::Node from,
const branchingtree::Node to 
)
overridevirtual

Implements Slic3r::branchingtree::Builder.

190{
191 Vec3d fromd = from.pos.cast<double>(), tod = to.pos.cast<double>();
192 double fromR = get_radius(from), toR = get_radius(to);
193 Beam beam{Ball{fromd, fromR}, Ball{tod, toR}};
194 auto hit = beam_mesh_hit(beam_ex_policy , m_sm.emesh, beam,
196
197 bool ret = hit.distance() > (tod - fromd).norm();
198
199 return ret;
200}
double get_radius(const branchingtree::Node &j) const
Definition BranchingTreeSLA.cpp:33
constexpr const auto & beam_ex_policy
Definition BranchingTreeSLA.cpp:16
Eigen::Matrix< double, 3, 1, Eigen::DontAlign > Vec3d
Definition SpatIndex.hpp:15
Beam_<> Beam
Definition SupportTreeUtils.hpp:143
Hit beam_mesh_hit(Ex policy, const AABBMesh &mesh, const Beam_< RayCount > &beam, double sd)
Definition SupportTreeUtils.hpp:146
static const double constexpr safety_distance_mm
Definition SupportTree.hpp:101
AABBMesh emesh
Definition SupportTree.hpp:115
SupportTreeConfig cfg
Definition SupportTree.hpp:117

References Slic3r::sla::beam_ex_policy, Slic3r::sla::beam_mesh_hit(), Slic3r::sla::SupportableMesh::cfg, Slic3r::sla::SupportableMesh::emesh, get_radius(), m_sm, Slic3r::branchingtree::Node::pos, and Slic3r::sla::SupportTreeConfig::safety_distance_mm.

+ Here is the call graph for this function:

◆ add_ground_bridge()

bool Slic3r::sla::BranchingTreeBuilder::add_ground_bridge ( const branchingtree::Node from,
const branchingtree::Node to 
)
overridevirtual

Implements Slic3r::branchingtree::Builder.

228{
229 bool ret = false;
230
231 namespace bgi = boost::geometry::index;
232
233 auto it = m_gnd_connections.find(from.id);
234 const GroundConnection *connptr = nullptr;
235
236 if (it == m_gnd_connections.end()) {
237 sla::Junction j{from.pos.cast<double>(), get_radius(from)};
238 Vec3d init_dir = (to.pos - from.pos).cast<double>().normalized();
239
241 get_radius(to), init_dir);
242
243 // Remember that this node was tested if can go to ground, don't
244 // test it with any other destination ground point because
245 // it is unlikely that search_ground_route would find a better solution
246 connptr = &(m_gnd_connections[from.id] = conn);
247 } else {
248 connptr = &(it->second);
249 }
250
251 if (connptr && *connptr) {
252 m_pillars.emplace_back(from);
253 ret = true;
254 build_subtree(from.id);
255 }
256
257 return ret;
258}
std::map< int, GroundConnection > m_gnd_connections
Definition BranchingTreeSLA.cpp:26
std::vector< branchingtree::Node > m_pillars
Definition BranchingTreeSLA.cpp:23
void build_subtree(size_t root)
Definition BranchingTreeSLA.cpp:42
GroundConnection deepsearch_ground_connection(Ex policy, const SupportableMesh &sm, const Junction &source, WideningFn &&wideningfn, const Vec3d &init_dir=DOWN)
Definition SupportTreeUtils.hpp:596

References Slic3r::sla::beam_ex_policy, build_subtree(), Slic3r::sla::deepsearch_ground_connection(), get_radius(), Slic3r::branchingtree::Node::id, m_gnd_connections, m_pillars, m_sm, and Slic3r::branchingtree::Node::pos.

Referenced by discard_subtree_rescure(), and report_unroutable().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_merger()

bool Slic3r::sla::BranchingTreeBuilder::add_merger ( const branchingtree::Node node,
const branchingtree::Node closest,
const branchingtree::Node merge_node 
)
overridevirtual

Implements Slic3r::branchingtree::Builder.

205{
206 Vec3d from1d = node.pos.cast<double>(),
207 from2d = closest.pos.cast<double>(),
208 tod = merge_node.pos.cast<double>();
209
210 double mergeR = get_radius(merge_node);
211 double nodeR = get_radius(node);
212 double closestR = get_radius(closest);
213 Beam beam1{Ball{from1d, nodeR}, Ball{tod, mergeR}};
214 Beam beam2{Ball{from2d, closestR}, Ball{tod, mergeR}};
215
216 auto sd = m_sm.cfg.safety_distance_mm ;
217 auto hit1 = beam_mesh_hit(beam_ex_policy , m_sm.emesh, beam1, sd);
218 auto hit2 = beam_mesh_hit(beam_ex_policy , m_sm.emesh, beam2, sd);
219
220 bool ret = hit1.distance() > (tod - from1d).norm() &&
221 hit2.distance() > (tod - from2d).norm();
222
223 return ret;
224}

References Slic3r::sla::beam_ex_policy, Slic3r::sla::beam_mesh_hit(), Slic3r::sla::SupportableMesh::cfg, Slic3r::sla::SupportableMesh::emesh, get_radius(), m_sm, Slic3r::branchingtree::Node::pos, and Slic3r::sla::SupportTreeConfig::safety_distance_mm.

+ Here is the call graph for this function:

◆ add_mesh_bridge()

bool Slic3r::sla::BranchingTreeBuilder::add_mesh_bridge ( const branchingtree::Node from,
const branchingtree::Node to 
)
overridevirtual

Implements Slic3r::branchingtree::Builder.

262{
263 if (from.weight > m_sm.cfg.max_weight_on_model_support)
264 return false;
265
266 sla::Junction fromj = {from.pos.cast<double>(), get_radius(from)};
267
268 auto anchor = m_sm.cfg.ground_facing_only ?
269 std::optional<Anchor>{} : // If no mesh connections are allowed
271 to.pos.cast<double>());
272
273 if (anchor) {
274 sla::Junction toj = {anchor->junction_point(), anchor->r_back_mm};
275
277 Beam{{fromj.pos, fromj.r}, {toj.pos, toj.r}}, 0.);
278
279 if (hit.distance() > distance(fromj.pos, toj.pos)) {
280 m_builder.add_diffbridge(fromj.pos, toj.pos, fromj.r, toj.r);
281 m_builder.add_anchor(*anchor);
282
283 build_subtree(from.id);
284 } else {
285 anchor.reset();
286 }
287 }
288
289 return bool(anchor);
290}
const Anchor & add_anchor(Args &&...args)
Definition SupportTreeBuilder.hpp:295
const DiffBridge & add_diffbridge(Args &&... args)
Definition SupportTreeBuilder.hpp:375
std::optional< Anchor > calculate_anchor_placement(Ex policy, const SupportableMesh &sm, const Junction &from, const Vec3d &to_hint)
Definition SupportTreeUtils.hpp:830
T distance(const Vec< I, T > &p)
Definition SupportTreeBuilder.hpp:52
double max_weight_on_model_support
Definition SupportTree.hpp:78
bool ground_facing_only
Definition SupportTree.hpp:45

References Slic3r::sla::SupportTreeBuilder::add_anchor(), Slic3r::sla::SupportTreeBuilder::add_diffbridge(), Slic3r::sla::beam_ex_policy, Slic3r::sla::beam_mesh_hit(), build_subtree(), Slic3r::sla::calculate_anchor_placement(), Slic3r::sla::SupportableMesh::cfg, Slic3r::sla::distance(), Slic3r::sla::SupportableMesh::emesh, get_radius(), Slic3r::sla::SupportTreeConfig::ground_facing_only, Slic3r::branchingtree::Node::id, m_builder, m_sm, Slic3r::sla::SupportTreeConfig::max_weight_on_model_support, Slic3r::branchingtree::Node::pos, Slic3r::sla::Junction::pos, Slic3r::sla::Junction::r, and Slic3r::branchingtree::Node::weight.

+ Here is the call graph for this function:

◆ build_subtree()

void Slic3r::sla::BranchingTreeBuilder::build_subtree ( size_t  root)
inlineprivate
43 {
44 traverse(m_cloud, root, [this](const branchingtree::Node &node) {
45 if (node.left >= 0 && node.right >= 0) {
46 auto nparent = m_cloud.get(node.id);
47 auto nleft = m_cloud.get(node.left);
48 auto nright = m_cloud.get(node.right);
49 Vec3d from1d = nleft.pos.cast<double>();
50 Vec3d from2d = nright.pos.cast<double>();
51 Vec3d tod = nparent.pos.cast<double>();
52 double mergeR = get_radius(nparent);
53 double leftR = get_radius(nleft);
54 double rightR = get_radius(nright);
55
56 m_builder.add_diffbridge(from1d, tod, leftR, mergeR);
57 m_builder.add_diffbridge(from2d, tod, rightR, mergeR);
58 m_builder.add_junction(tod, mergeR);
59 } else if (int child = node.left + node.right + 1; child >= 0) {
60 auto from = m_cloud.get(child);
61 auto to = m_cloud.get(node.id);
62 auto tod = to.pos.cast<double>();
63 double toR = get_radius(to);
64 m_builder.add_diffbridge(from.pos.cast<double>(),
65 tod,
66 get_radius(from),
67 toR);
68 m_builder.add_junction(tod, toR);
69 }
70 });
71 }
const Node & get(size_t node_id) const
Definition PointCloud.hpp:140
const Junction & add_junction(Args &&... args)
Definition SupportTreeBuilder.hpp:342
if(!(yy_init))
Definition lexer.c:1190
void traverse(const Tree< Dims, T > &tree, Predicate &&pred, Fn &&callback)
Definition AABBTreeIndirect.hpp:981
Vec3f pos
Definition BranchingTree.hpp:69

References Slic3r::sla::SupportTreeBuilder::add_diffbridge(), Slic3r::sla::SupportTreeBuilder::add_junction(), Slic3r::branchingtree::PointCloud::get(), get_radius(), Slic3r::branchingtree::Node::id, if(), Slic3r::branchingtree::Node::left, m_builder, m_cloud, Slic3r::branchingtree::Node::pos, and Slic3r::branchingtree::Node::right.

Referenced by add_ground_bridge(), and add_mesh_bridge().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ discard_subtree()

void Slic3r::sla::BranchingTreeBuilder::discard_subtree ( size_t  root)
inlineprivate
74 {
75 // Discard all the support points connecting to this branch.
76 traverse(m_cloud, root, [this](const branchingtree::Node &node) {
77 int suppid_parent = m_cloud.get_leaf_id(node.id);
78 int suppid_left = m_cloud.get_leaf_id(node.left);
79 int suppid_right = m_cloud.get_leaf_id(node.right);
80 if (suppid_parent >= 0)
81 m_unroutable_pinheads.emplace_back(suppid_parent);
82 if (suppid_left >= 0)
83 m_unroutable_pinheads.emplace_back(suppid_left);
84 if (suppid_right >= 0)
85 m_unroutable_pinheads.emplace_back(suppid_right);
86 });
87 }
int get_leaf_id(size_t node_id) const
Definition PointCloud.hpp:155
std::vector< size_t > m_unroutable_pinheads
Definition BranchingTreeSLA.cpp:40

References Slic3r::branchingtree::PointCloud::get_leaf_id(), Slic3r::branchingtree::Node::id, Slic3r::branchingtree::Node::left, m_cloud, m_unroutable_pinheads, and Slic3r::branchingtree::Node::right.

+ Here is the call graph for this function:

◆ discard_subtree_rescure()

void Slic3r::sla::BranchingTreeBuilder::discard_subtree_rescure ( size_t  root)
inlineprivate
90 {
91 // Discard all the support points connecting to this branch.
92 // As a last resort, try to route child nodes to ground and stop
93 // traversing if any child branch succeeds.
94 traverse(m_cloud, root, [this](const branchingtree::Node &node) {
95 branchingtree::TraverseReturnT ret{true, true};
96
97 int suppid_parent = m_cloud.get_leaf_id(node.id);
98 int suppid_left = branchingtree::Node::ID_NONE;
99 int suppid_right = branchingtree::Node::ID_NONE;
100
101 double glvl = ground_level(m_sm);
102 branchingtree::Node dst = node;
103 dst.pos.z() = glvl;
104 dst.weight += node.pos.z() - glvl;
105
106 if (node.left >= 0 && add_ground_bridge(m_cloud.get(node.left), dst))
107 ret.to_left = false;
108 else
109 suppid_left = m_cloud.get_leaf_id(node.left);
110
111 if (node.right >= 0 && add_ground_bridge(m_cloud.get(node.right), dst))
112 ret.to_right = false;
113 else
114 suppid_right = m_cloud.get_leaf_id(node.right);
115
116 if (suppid_parent >= 0)
117 m_unroutable_pinheads.emplace_back(suppid_parent);
118 if (suppid_left >= 0)
119 m_unroutable_pinheads.emplace_back(suppid_left);
120 if (suppid_right >= 0)
121 m_unroutable_pinheads.emplace_back(suppid_right);
122
123 return ret;
124 });
125 }
bool add_ground_bridge(const branchingtree::Node &from, const branchingtree::Node &) override
Definition BranchingTreeSLA.cpp:226
double ground_level(const SupportableMesh &sm)
Definition SupportTree.hpp:134
static constexpr int ID_NONE
Definition BranchingTree.hpp:65

References add_ground_bridge(), Slic3r::branchingtree::PointCloud::get(), Slic3r::branchingtree::PointCloud::get_leaf_id(), Slic3r::sla::ground_level(), Slic3r::branchingtree::Node::id, Slic3r::branchingtree::Node::ID_NONE, Slic3r::branchingtree::Node::left, m_cloud, m_sm, m_unroutable_pinheads, Slic3r::branchingtree::Node::pos, Slic3r::branchingtree::Node::right, and Slic3r::branchingtree::Node::weight.

Referenced by report_unroutable().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_radius()

double Slic3r::sla::BranchingTreeBuilder::get_radius ( const branchingtree::Node j) const
inlineprivate
34 {
35 double w = WIDENING_SCALE * m_sm.cfg.pillar_widening_factor * j.weight;
36
37 return double(j.Rmin) + w;
38 }
static constexpr double WIDENING_SCALE
Definition BranchingTreeSLA.cpp:31
double pillar_widening_factor
Definition SupportTree.hpp:51

References Slic3r::sla::SupportableMesh::cfg, m_sm, Slic3r::sla::SupportTreeConfig::pillar_widening_factor, Slic3r::branchingtree::Node::Rmin, Slic3r::branchingtree::Node::weight, and WIDENING_SCALE.

Referenced by add_bridge(), add_ground_bridge(), add_merger(), add_mesh_bridge(), and build_subtree().

+ Here is the caller graph for this function:

◆ ground_conn()

const GroundConnection * Slic3r::sla::BranchingTreeBuilder::ground_conn ( size_t  pillar) const
inline
177 {
178 const GroundConnection *ret = nullptr;
179
180 auto it = m_gnd_connections.find(m_pillars[pillar].id);
181 if (it != m_gnd_connections.end())
182 ret = &it->second;
183
184 return ret;
185 }

References m_gnd_connections, and m_pillars.

Referenced by Slic3r::sla::build_pillars().

+ Here is the caller graph for this function:

◆ is_valid()

bool Slic3r::sla::BranchingTreeBuilder::is_valid ( ) const
inlineoverridevirtual

Reimplemented from Slic3r::branchingtree::Builder.

172{ return !m_builder.ctl().stopcondition(); }
const JobController & ctl() const
Definition SupportTreeBuilder.hpp:256
StopCond stopcondition
Definition JobController.hpp:21

References Slic3r::sla::SupportTreeBuilder::ctl(), m_builder, and Slic3r::sla::JobController::stopcondition.

+ Here is the call graph for this function:

◆ pillars()

const std::vector< branchingtree::Node > & Slic3r::sla::BranchingTreeBuilder::pillars ( ) const
inline
174{ return m_pillars; }

References m_pillars.

Referenced by Slic3r::sla::build_pillars().

+ Here is the caller graph for this function:

◆ report_unroutable()

void Slic3r::sla::BranchingTreeBuilder::report_unroutable ( const branchingtree::Node j)
inlineoverridevirtual

Implements Slic3r::branchingtree::Builder.

151 {
152 double glvl = ground_level(m_sm);
153 branchingtree::Node dst = j;
154 dst.pos.z() = glvl;
155 dst.weight += j.pos.z() - glvl;
156 if (add_ground_bridge(j, dst))
157 return;
158
159 BOOST_LOG_TRIVIAL(warning) << "Cannot route junction at " << j.pos.x()
160 << " " << j.pos.y() << " " << j.pos.z();
161
162 // Discard all the support points connecting to this branch.
164// discard_subtree(j.id);
165 }
void discard_subtree_rescure(size_t root)
Definition BranchingTreeSLA.cpp:89

References add_ground_bridge(), discard_subtree_rescure(), Slic3r::sla::ground_level(), Slic3r::branchingtree::Node::id, m_sm, Slic3r::branchingtree::Node::pos, and Slic3r::branchingtree::Node::weight.

+ Here is the call graph for this function:

◆ suggest_avoidance()

std::optional< Vec3f > Slic3r::sla::BranchingTreeBuilder::suggest_avoidance ( const branchingtree::Node from,
float  max_bridge_len 
) const
overridevirtual

Reimplemented from Slic3r::branchingtree::Builder.

313{
314 std::optional<Vec3f> ret;
315
316 double glvl = ground_level(m_sm);
317 branchingtree::Node dst = from;
318 dst.pos.z() = glvl;
319 dst.weight += from.pos.z() - glvl;
320 sla::Junction j{from.pos.cast<double>(), get_radius(from)};
321
322 auto found_it = m_gnd_connections.end();
323 {
324 std::lock_guard lk{m_gnd_connections_mtx};
325 found_it = m_gnd_connections.find(from.id);
326 }
327
328 if (found_it != m_gnd_connections.end()) {
329 ret = get_avoidance(found_it->second, max_bridge_len);
330 } else {
333
334 {
335 std::lock_guard lk{m_gnd_connections_mtx};
336 m_gnd_connections[from.id] = conn;
337 }
338
339 ret = get_avoidance(conn, max_bridge_len);
340 }
341
342 return ret;
343}
execution::SpinningMutex< ExecutionTBB > m_gnd_connections_mtx
Definition BranchingTreeSLA.cpp:27
static std::optional< Vec3f > get_avoidance(const GroundConnection &conn, float maxdist)
Definition BranchingTreeSLA.cpp:292
const Vec3d DOWN
Definition SupportTreeBuilder.hpp:61

References Slic3r::sla::beam_ex_policy, Slic3r::sla::deepsearch_ground_connection(), Slic3r::sla::DOWN, Slic3r::sla::get_avoidance(), Slic3r::sla::ground_level(), Slic3r::branchingtree::Node::id, Slic3r::branchingtree::Node::pos, and Slic3r::branchingtree::Node::weight.

+ Here is the call graph for this function:

◆ unroutable_pinheads()

const std::vector< size_t > & Slic3r::sla::BranchingTreeBuilder::unroutable_pinheads ( ) const
inline
168 {
170 }

References m_unroutable_pinheads.

Member Data Documentation

◆ m_builder

SupportTreeBuilder& Slic3r::sla::BranchingTreeBuilder::m_builder
private

◆ m_cloud

const branchingtree::PointCloud& Slic3r::sla::BranchingTreeBuilder::m_cloud
private

◆ m_gnd_connections

std::map<int, GroundConnection> Slic3r::sla::BranchingTreeBuilder::m_gnd_connections
mutableprivate

Referenced by add_ground_bridge(), and ground_conn().

◆ m_gnd_connections_mtx

execution::SpinningMutex<ExecutionTBB> Slic3r::sla::BranchingTreeBuilder::m_gnd_connections_mtx
mutableprivate

◆ m_pillars

std::vector<branchingtree::Node> Slic3r::sla::BranchingTreeBuilder::m_pillars
private

◆ m_sm

◆ m_unroutable_pinheads

std::vector<size_t> Slic3r::sla::BranchingTreeBuilder::m_unroutable_pinheads
private

◆ WIDENING_SCALE

constexpr double Slic3r::sla::BranchingTreeBuilder::WIDENING_SCALE = 0.05
staticconstexprprivate

Referenced by get_radius().


The documentation for this class was generated from the following file: