Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::FillLightning::Node Class Reference

#include <src/libslic3r/Fill/Lightning/TreeNode.hpp>

+ Inheritance diagram for Slic3r::FillLightning::Node:
+ Collaboration diagram for Slic3r::FillLightning::Node:

Classes

struct  RectilinearJunction
 

Public Member Functions

const PointgetLocation () const
 
void setLocation (const Point &p)
 
NodeSPtr addChild (const Point &p)
 
NodeSPtr addChild (NodeSPtr &new_child)
 
void propagateToNextLayer (std::vector< NodeSPtr > &next_trees, const Polygons &next_outlines, const EdgeGrid::Grid &outline_locator, coord_t prune_distance, coord_t smooth_magnitude, coord_t max_remove_colinear_dist) const
 
void visitBranches (const std::function< void(const Point &, const Point &)> &visitor) const
 
void visitNodes (const std::function< void(NodeSPtr)> &visitor)
 
coord_t getWeightedDistance (const Point &unsupported_location, const coord_t &supporting_radius) const
 
bool isRoot () const
 
void reroot (const NodeSPtr &new_parent=nullptr)
 
NodeSPtr closestNode (const Point &loc)
 
bool hasOffspring (const NodeSPtr &to_be_checked) const
 
 Node ()=delete
 
void convertToPolylines (Polylines &output, coord_t line_overlap) const
 
const std::optional< Point > & getLastGroundingLocation () const
 

Static Public Member Functions

template<typename ... Arg>
static NodeSPtr create (Arg &&...arg)
 

Protected Member Functions

 Node (const Point &p, const std::optional< Point > &last_grounding_location=std::nullopt)
 
NodeSPtr deepCopy () const
 
bool realign (const Polygons &outlines, const EdgeGrid::Grid &outline_locator, std::vector< NodeSPtr > &rerooted_parts)
 
void straighten (coord_t magnitude, coord_t max_remove_colinear_dist)
 
RectilinearJunction straighten (coord_t magnitude, const Point &junction_above, coord_t accumulated_dist, int64_t max_remove_colinear_dist2)
 
coord_t prune (const coord_t &distance)
 
void convertToPolylines (size_t long_line_idx, Polylines &output) const
 
void removeJunctionOverlap (Polylines &polylines, coord_t line_overlap) const
 

Protected Attributes

bool m_is_root
 
Point m_p
 
std::weak_ptr< Nodem_parent
 
std::vector< NodeSPtrm_children
 
std::optional< Pointm_last_grounding_location
 

Friends

BoundingBox get_extents (const NodeSPtr &root_node)
 
BoundingBox get_extents (const std::vector< NodeSPtr > &tree_roots)
 

Detailed Description

A single vertex of a Lightning Tree, the structure that determines the paths to be printed to form Lightning Infill.

In essence these vertices are just a position linked to other positions in 2D. The nodes have a hierarchical structure of parents and children, forming a tree. The class also has some helper functions specific to Lightning Infill e.g. to straighten the paths around this node.


Class Documentation

◆ Slic3r::FillLightning::Node::RectilinearJunction

struct Slic3r::FillLightning::Node::RectilinearJunction
Class Members
Point junction_loc junction location below
coord_t total_recti_dist rectilinear distance along the tree from the last junction above to the junction below

Constructor & Destructor Documentation

◆ Node() [1/2]

Slic3r::FillLightning::Node::Node ( )
delete

◆ Node() [2/2]

Slic3r::FillLightning::Node::Node ( const Point p,
const std::optional< Point > &  last_grounding_location = std::nullopt 
)
explicitprotected

Construct a new node, either for insertion in a tree or as root.

Parameters
pThe physical location in the 2D layer that this node represents. Connecting other nodes to this node indicates that a line segment should be drawn between those two physical positions.
87 :
88 m_is_root(true), m_p(p), m_last_grounding_location(last_grounding_location)
89{}
std::optional< Point > m_last_grounding_location
Definition TreeNode.hpp:270
Point m_p
Definition TreeNode.hpp:266
bool m_is_root
Definition TreeNode.hpp:265

Member Function Documentation

◆ addChild() [1/2]

NodeSPtr Slic3r::FillLightning::Node::addChild ( const Point p)

Construct a new Node instance and add it as a child of this node.

Parameters
pThe location of the new node.
Returns
A shared pointer to the new node.
35{
36 assert(m_p != child_loc);
37 NodeSPtr child = Node::create(child_loc);
38 return addChild(child);
39}
static NodeSPtr create(Arg &&...arg)
Definition TreeNode.hpp:45
NodeSPtr addChild(const Point &p)
Definition TreeNode.cpp:34
std::shared_ptr< Node > NodeSPtr
Definition Layer.hpp:20

References addChild(), create(), and m_p.

Referenced by addChild().

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

◆ addChild() [2/2]

NodeSPtr Slic3r::FillLightning::Node::addChild ( NodeSPtr new_child)

Add an existing Node as a child of this node.

Parameters
new_childThe node that must be added as a child.
Returns
Always returns new_child.
42{
43 assert(new_child != shared_from_this());
44 //assert(p != new_child->p); // NOTE: No problem for now. Issue to solve later. Maybe even afetr final. Low prio.
45 m_children.push_back(new_child);
46 new_child->m_parent = shared_from_this();
47 new_child->m_is_root = false;
48 return new_child;
49}
std::vector< NodeSPtr > m_children
Definition TreeNode.hpp:268

References m_children.

◆ closestNode()

NodeSPtr Slic3r::FillLightning::Node::closestNode ( const Point loc)

Retrieves the closest node to the specified location.

Parameters
locThe specified location.
Returns
The branch that starts at the position closest to the location within this tree.
128{
129 NodeSPtr result = shared_from_this();
130 auto closest_dist2 = coord_t((m_p - loc).cast<double>().norm());
131
132 for (const auto& child : m_children) {
133 NodeSPtr candidate_node = child->closestNode(loc);
134 const auto child_dist2 = coord_t((candidate_node->m_p - loc).cast<double>().norm());
135 if (child_dist2 < closest_dist2) {
136 closest_dist2 = child_dist2;
137 result = candidate_node;
138 }
139 }
140
141 return result;
142}
int32_t coord_t
Definition libslic3r.h:39

References m_children, and m_p.

◆ convertToPolylines() [1/2]

void Slic3r::FillLightning::Node::convertToPolylines ( Polylines output,
coord_t  line_overlap 
) const

Convert the tree into polylines

At each junction one line is chosen at random to continue

The lines start at a leaf and end in a junction

Parameters
outputall branches in this tree connected into polylines
339{
340 Polylines result;
341 result.emplace_back();
342 convertToPolylines(0, result);
343 removeJunctionOverlap(result, line_overlap);
344 append(output, std::move(result));
345}
void convertToPolylines(Polylines &output, coord_t line_overlap) const
Definition TreeNode.cpp:338
void removeJunctionOverlap(Polylines &polylines, coord_t line_overlap) const
Definition TreeNode.cpp:367
std::vector< Polyline > Polylines
Definition Polyline.hpp:14
void append(std::vector< T, Alloc > &dest, const std::vector< T, Alloc2 > &src)
Definition libslic3r.h:110

References Slic3r::append().

Referenced by convertToPolylines().

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

◆ convertToPolylines() [2/2]

void Slic3r::FillLightning::Node::convertToPolylines ( size_t  long_line_idx,
Polylines output 
) const
protected

Convert the tree into polylines

At each junction one line is chosen at random to continue

The lines start at a leaf and end in a junction

Parameters
long_linea reference to a polyline in output which to continue building on in the recursion
outputall branches in this tree connected into polylines
348{
349 if (m_children.empty()) {
350 output[long_line_idx].points.push_back(m_p);
351 return;
352 }
353 size_t first_child_idx = rand() % m_children.size();
354 m_children[first_child_idx]->convertToPolylines(long_line_idx, output);
355 output[long_line_idx].points.push_back(m_p);
356
357 for (size_t idx_offset = 1; idx_offset < m_children.size(); idx_offset++) {
358 size_t child_idx = (first_child_idx + idx_offset) % m_children.size();
359 const Node& child = *m_children[child_idx];
360 output.emplace_back();
361 size_t child_line_idx = output.size() - 1;
362 child.convertToPolylines(child_line_idx, output);
363 output[child_line_idx].points.emplace_back(m_p);
364 }
365}

References convertToPolylines().

+ Here is the call graph for this function:

◆ create()

template<typename ... Arg>
static NodeSPtr Slic3r::FillLightning::Node::create ( Arg &&...  arg)
inlinestatic
46 {
47 struct EnableMakeShared : public Node
48 {
49 explicit EnableMakeShared(Arg&&...arg) : Node(std::forward<Arg>(arg)...) {}
50 };
51 return std::make_shared<EnableMakeShared>(std::forward<Arg>(arg)...);
52 }
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const ArgReturnType arg() const
Definition ArrayCwiseUnaryOps.h:57
STL namespace.

References arg().

Referenced by addChild(), and deepCopy().

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

◆ deepCopy()

NodeSPtr Slic3r::FillLightning::Node::deepCopy ( ) const
protected

Copy this node and its entire sub-tree.

Returns
The equivalent of this node in the copy (the root of the new sub- tree).
92{
93 NodeSPtr local_root = Node::create(m_p);
94 local_root->m_is_root = m_is_root;
95 if (m_is_root)
96 {
97 local_root->m_last_grounding_location = m_last_grounding_location.value_or(m_p);
98 }
99 local_root->m_children.reserve(m_children.size());
100 for (const auto& node : m_children)
101 {
102 NodeSPtr child = node->deepCopy();
103 child->m_parent = local_root;
104 local_root->m_children.push_back(child);
105 }
106 return local_root;
107}

References create(), m_children, m_is_root, m_last_grounding_location, and m_p.

Referenced by propagateToNextLayer().

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

◆ getLastGroundingLocation()

const std::optional< Point > & Slic3r::FillLightning::Node::getLastGroundingLocation ( ) const
inline

If this was ever a direct child of the root, it'll have a previous grounding location.

This needs to be known when roots are reconnected, so that the last (higher) layer is supported by the next one.

References m_last_grounding_location.

◆ getLocation()

const Point & Slic3r::FillLightning::Node::getLocation ( ) const
inline

Get the position on this layer that this node represents, a vertex of the path to print.

Returns
The position that this node represents.
59{ return m_p; }

References m_p.

Referenced by getWeightedDistance().

+ Here is the caller graph for this function:

◆ getWeightedDistance()

coord_t Slic3r::FillLightning::Node::getWeightedDistance ( const Point unsupported_location,
const coord_t supporting_radius 
) const

Get a weighted distance from an unsupported point to this node (given the current supporting radius).

When attaching a unsupported location to a node, not all nodes have the same priority. (Eucludian) closer nodes are prioritised, but that's not the whole story. For instance, we give some nodes a 'valence boost' depending on the nr. of branches.

Parameters
unsupported_locationThe (unsuppported) location of which the weighted distance needs to be calculated.
supporting_radiusThe maximum distance which can be bridged without (infill) supporting it.
Returns
The weighted distance.
11{
12 constexpr coord_t min_valence_for_boost = 0;
13 constexpr coord_t max_valence_for_boost = 4;
14 constexpr coord_t valence_boost_multiplier = 4;
15
16 const size_t valence = (!m_is_root) + m_children.size();
17 const coord_t valence_boost = (min_valence_for_boost < valence && valence < max_valence_for_boost) ? valence_boost_multiplier * supporting_radius : 0;
18 const auto dist_here = coord_t((getLocation() - unsupported_location).cast<double>().norm());
19 return dist_here - valence_boost;
20}
const Point & getLocation() const
Definition TreeNode.hpp:59

References getLocation(), m_children, and m_is_root.

+ Here is the call graph for this function:

◆ hasOffspring()

bool Slic3r::FillLightning::Node::hasOffspring ( const NodeSPtr to_be_checked) const

Returns whether the given tree node is a descendant of this node.

If this node itself is given, it is also considered to be a descendant.

Parameters
to_be_checkedA node to find out whether it is a descendant of this node.
Returns
true if the given node is a descendant or this node itself, or false if it is not in the sub-tree.
23{
24 if (to_be_checked == shared_from_this())
25 return true;
26
27 for (auto& child_ptr : m_children)
28 if (child_ptr->hasOffspring(to_be_checked))
29 return true;
30
31 return false;
32}
bool hasOffspring(const NodeSPtr &to_be_checked) const
Definition TreeNode.cpp:22
if(!(yy_init))
Definition lexer.c:1190

References m_children.

◆ isRoot()

bool Slic3r::FillLightning::Node::isRoot ( ) const
inline

Returns whether this node is the root of a lightning tree. It is the root if it has no parents.

Returns
true if this node is the root (no parents) or false if it is a child node of some other node.
153{ return m_is_root; }

References m_is_root.

◆ propagateToNextLayer()

void Slic3r::FillLightning::Node::propagateToNextLayer ( std::vector< NodeSPtr > &  next_trees,
const Polygons next_outlines,
const EdgeGrid::Grid outline_locator,
coord_t  prune_distance,
coord_t  smooth_magnitude,
coord_t  max_remove_colinear_dist 
) const

Propagate this node's sub-tree to the next layer.

Creates a copy of this tree, realign it to the new layer boundaries next_outlines and reduce (i.e. prune and straighten) it. A copy of this node and all of its descendant nodes will be added to the next_trees vector.

Parameters
next_treesA collection of tree nodes to use for the next layer.
next_outlinesThe shape of the layer below, to make sure that the tree stays within the bounds of the infill area.
prune_distanceThe maximum distance that a leaf node may be moved such that it still supports the current node.
smooth_magnitudeThe maximum distance that a line may be shifted to straighten the tree's paths, such that it still supports the current paths.
max_remove_colinear_distThe maximum distance of a line-segment from which straightening may remove a colinear point.
58{
59 auto tree_below = deepCopy();
60 tree_below->prune(prune_distance);
61 tree_below->straighten(smooth_magnitude, max_remove_colinear_dist);
62 if (tree_below->realign(next_outlines, outline_locator, next_trees))
63 next_trees.push_back(tree_below);
64}
NodeSPtr deepCopy() const
Definition TreeNode.cpp:91

References deepCopy().

+ Here is the call graph for this function:

◆ prune()

coord_t Slic3r::FillLightning::Node::prune ( const coord_t distance)
protected

Prune the tree from the extremeties (leaf-nodes) until the pruning distance is reached.

Returns
The distance that has been pruned. If less than distance, then the whole tree was puned away.
302{
303 if (pruning_distance <= 0)
304 return 0;
305
306 coord_t max_distance_pruned = 0;
307 for (auto child_it = m_children.begin(); child_it != m_children.end(); ) {
308 auto& child = *child_it;
309 coord_t dist_pruned_child = child->prune(pruning_distance);
310 if (dist_pruned_child >= pruning_distance)
311 { // pruning is finished for child; dont modify further
312 max_distance_pruned = std::max(max_distance_pruned, dist_pruned_child);
313 ++child_it;
314 } else {
315 const Point a = getLocation();
316 const Point b = child->getLocation();
317 const Point ba = a - b;
318 const auto ab_len = coord_t(ba.cast<double>().norm());
319 if (dist_pruned_child + ab_len <= pruning_distance) {
320 // we're still in the process of pruning
321 assert(child->m_children.empty() && "when pruning away a node all it's children must already have been pruned away");
322 max_distance_pruned = std::max(max_distance_pruned, dist_pruned_child + ab_len);
323 child_it = m_children.erase(child_it);
324 } else {
325 // pruning stops in between this node and the child
326 const Point n = b + (ba.cast<double>().normalized() * (pruning_distance - dist_pruned_child)).cast<coord_t>();
327 assert(std::abs((n - b).cast<double>().norm() + dist_pruned_child - pruning_distance) < 10 && "total pruned distance must be equal to the pruning_distance");
328 max_distance_pruned = std::max(max_distance_pruned, pruning_distance);
329 child->setLocation(n);
330 ++child_it;
331 }
332 }
333 }
334
335 return max_distance_pruned;
336}
Kernel::Point_2 Point
Definition point_areas.cpp:20

◆ realign()

bool Slic3r::FillLightning::Node::realign ( const Polygons outlines,
const EdgeGrid::Grid outline_locator,
std::vector< NodeSPtr > &  rerooted_parts 
)
protected

Reconnect trees from the layer above to the new outlines of the lower layer.

Returns
Wether or not the root is kept (false is no, true is yes).
179{
180 if (outlines.empty())
181 return false;
182
183 if (contains(outlines, m_p)) {
184 // Only keep children that have an unbroken connection to here, realign will put the rest in rerooted parts due to recursion:
185 Point coll;
186 bool reground_me = false;
187 m_children.erase(std::remove_if(m_children.begin(), m_children.end(), [&](const NodeSPtr &child) {
188 bool connect_branch = child->realign(outlines, outline_locator, rerooted_parts);
189 // Find an intersection of the line segment from p to child->p, at maximum outline_locator.resolution() * 2 distance from p.
190 if (connect_branch && lineSegmentPolygonsIntersection(child->m_p, m_p, outline_locator, coll, outline_locator.resolution() * 2)) {
191 child->m_last_grounding_location.reset();
192 child->m_parent.reset();
193 child->m_is_root = true;
194 rerooted_parts.push_back(child);
195 reground_me = true;
196 connect_branch = false;
197 }
198 return ! connect_branch;
199 }), m_children.end());
200 if (reground_me)
202 return true;
203 }
204
205 // 'Lift' any decendants out of this tree:
206 for (auto& child : m_children)
207 if (child->realign(outlines, outline_locator, rerooted_parts)) {
208 child->m_last_grounding_location = m_p;
209 child->m_parent.reset();
210 child->m_is_root = true;
211 rerooted_parts.push_back(child);
212 }
213
214 m_children.clear();
215 return false;
216}
bool realign(const Polygons &outlines, const EdgeGrid::Grid &outline_locator, std::vector< NodeSPtr > &rerooted_parts)
Definition TreeNode.cpp:178
bool contains(const ContainerType &c, const ValueType &v)
Definition libslic3r.h:247

References Slic3r::contains(), m_children, m_last_grounding_location, and m_p.

+ Here is the call graph for this function:

◆ removeJunctionOverlap()

void Slic3r::FillLightning::Node::removeJunctionOverlap ( Polylines polylines,
coord_t  line_overlap 
) const
protected
368{
369 const coord_t reduction = line_overlap;
370 size_t res_line_idx = 0;
371 while (res_line_idx < result_lines.size()) {
372 Polyline &polyline = result_lines[res_line_idx];
373 if (polyline.size() <= 1) {
374 polyline = std::move(result_lines.back());
375 result_lines.pop_back();
376 continue;
377 }
378
379 coord_t to_be_reduced = reduction;
380 Point a = polyline.back();
381 for (int point_idx = int(polyline.size()) - 2; point_idx >= 0; point_idx--) {
382 const Point b = polyline.points[point_idx];
383 const Point ab = b - a;
384 const auto ab_len = coord_t(ab.cast<double>().norm());
385 if (ab_len >= to_be_reduced) {
386 polyline.points.back() = a + (ab.cast<double>() * (double(to_be_reduced) / ab_len)).cast<coord_t>();
387 break;
388 } else {
389 to_be_reduced -= ab_len;
390 polyline.points.pop_back();
391 }
392 a = b;
393 }
394
395 if (polyline.size() <= 1) {
396 polyline = std::move(result_lines.back());
397 result_lines.pop_back();
398 } else
399 ++ res_line_idx;
400 }
401}

References Slic3r::MultiPoint::back(), Slic3r::MultiPoint::points, and Slic3r::MultiPoint::size().

+ Here is the call graph for this function:

◆ reroot()

void Slic3r::FillLightning::Node::reroot ( const NodeSPtr new_parent = nullptr)

Reverse the parent-child relationship all the way to the root, from this node onward. This has the effect of 're-rooting' the tree at the current node if no immediate parent is given as argument. That is, the current node will become the root, it's (former) parent if any, will become one of it's children. This is then recursively bubbled up until it reaches the (former) root, which then will become a leaf.

Parameters
new_parentThe (new) parent-node of the root, useful for recursing or immediately attaching the node to another tree.
110{
111 if (! m_is_root) {
112 auto old_parent = m_parent.lock();
113 old_parent->reroot(shared_from_this());
114 m_children.push_back(old_parent);
115 }
116
117 if (new_parent) {
118 m_children.erase(std::remove(m_children.begin(), m_children.end(), new_parent), m_children.end());
119 m_is_root = false;
120 m_parent = new_parent;
121 } else {
122 m_is_root = true;
123 m_parent.reset();
124 }
125}
std::weak_ptr< Node > m_parent
Definition TreeNode.hpp:267

References m_children, m_is_root, and m_parent.

◆ setLocation()

void Slic3r::FillLightning::Node::setLocation ( const Point p)
inline

Change the position on this layer that the node represents.

Parameters
pThe position that the node needs to represent.
65{ m_p = p; }

References m_p.

◆ straighten() [1/2]

Node::RectilinearJunction Slic3r::FillLightning::Node::straighten ( coord_t  magnitude,
const Point junction_above,
coord_t  accumulated_dist,
int64_t  max_remove_colinear_dist2 
)
protected

Recursive part of straighten(.)

Parameters
junction_aboveThe last seen junction with multiple children above
accumulated_distThe distance along the tree from the last seen junction to this node
max_remove_colinear_dist2Maximum distance squared of the (compound) line-segment from which a co-linear point may be removed.
Returns
the total distance along the tree from the last junction above to the first next junction below and the location of the next junction below
228{
229 constexpr coord_t junction_magnitude_factor_numerator = 3;
230 constexpr coord_t junction_magnitude_factor_denominator = 4;
231
232 const coord_t junction_magnitude = magnitude * junction_magnitude_factor_numerator / junction_magnitude_factor_denominator;
233 if (m_children.size() == 1)
234 {
235 auto child_p = m_children.front();
236 auto child_dist = coord_t((m_p - child_p->m_p).cast<double>().norm());
237 RectilinearJunction junction_below = child_p->straighten(magnitude, junction_above, accumulated_dist + child_dist, max_remove_colinear_dist2);
238 coord_t total_dist_to_junction_below = junction_below.total_recti_dist;
239 const Point& a = junction_above;
240 Point b = junction_below.junction_loc;
241 if (a != b) // should always be true!
242 {
243 Point ab = b - a;
244 Point destination = (a.cast<int64_t>() + ab.cast<int64_t>() * int64_t(accumulated_dist) / std::max(int64_t(1), int64_t(total_dist_to_junction_below))).cast<coord_t>();
245 if ((destination - m_p).cast<int64_t>().squaredNorm() <= int64_t(magnitude) * int64_t(magnitude))
246 m_p = destination;
247 else
248 m_p += ((destination - m_p).cast<double>().normalized() * magnitude).cast<coord_t>();
249 }
250 { // remove nodes on linear segments
251 constexpr coord_t close_enough = 10;
252
253 child_p = m_children.front(); //recursive call to straighten might have removed the child
254 const NodeSPtr& parent_node = m_parent.lock();
255 if (parent_node &&
256 (child_p->m_p - parent_node->m_p).cast<int64_t>().squaredNorm() < max_remove_colinear_dist2 &&
257 Line::distance_to_squared(m_p, parent_node->m_p, child_p->m_p) < close_enough * close_enough) {
258 child_p->m_parent = m_parent;
259 for (auto& sibling : parent_node->m_children)
260 { // find this node among siblings
261 if (sibling == shared_from_this())
262 {
263 sibling = child_p; // replace this node by child
264 break;
265 }
266 }
267 }
268 }
269 return junction_below;
270 }
271 else
272 {
273 constexpr coord_t weight = 1000;
274 Point junction_moving_dir = ((junction_above - m_p).cast<double>().normalized() * weight).cast<coord_t>();
275 bool prevent_junction_moving = false;
276 for (auto& child_p : m_children)
277 {
278 const auto child_dist = coord_t((m_p - child_p->m_p).cast<double>().norm());
279 RectilinearJunction below = child_p->straighten(magnitude, m_p, child_dist, max_remove_colinear_dist2);
280
281 junction_moving_dir += ((below.junction_loc - m_p).cast<double>().normalized() * weight).cast<coord_t>();
282 if (below.total_recti_dist < magnitude) // TODO: make configurable?
283 {
284 prevent_junction_moving = true; // prevent flipflopping in branches due to straightening and junctoin moving clashing
285 }
286 }
287 if (junction_moving_dir != Point(0, 0) && ! m_children.empty() && ! m_is_root && ! prevent_junction_moving)
288 {
289 auto junction_moving_dir_len = coord_t(junction_moving_dir.norm());
290 if (junction_moving_dir_len > junction_magnitude)
291 {
292 junction_moving_dir = junction_moving_dir * junction_magnitude / junction_moving_dir_len;
293 }
294 m_p += junction_moving_dir;
295 }
296 return RectilinearJunction{ accumulated_dist, m_p };
297 }
298}
double distance_to_squared(const Point &point) const
Definition Line.hpp:169
__int64 int64_t
Definition unistd.h:76

References Slic3r::Line::distance_to_squared(), Slic3r::FillLightning::Node::RectilinearJunction::junction_loc, and Slic3r::FillLightning::Node::RectilinearJunction::total_recti_dist.

+ Here is the call graph for this function:

◆ straighten() [2/2]

void Slic3r::FillLightning::Node::straighten ( coord_t  magnitude,
coord_t  max_remove_colinear_dist 
)
protected

Smoothen the tree to make it a bit more printable, while still supporting the trees above.

Parameters
magnitudeThe maximum allowed distance to move the node.
max_remove_colinear_distMaximum distance of the (compound) line-segment from which a co-linear point may be removed.
219{
220 straighten(magnitude, m_p, 0, int64_t(max_remove_colinear_dist) * int64_t(max_remove_colinear_dist));
221}
void straighten(coord_t magnitude, coord_t max_remove_colinear_dist)
Definition TreeNode.cpp:218

◆ visitBranches()

void Slic3r::FillLightning::Node::visitBranches ( const std::function< void(const Point &, const Point &)> &  visitor) const

Executes a given function for every line segment in this node's sub-tree.

The function takes two Point arguments. These arguments will be filled in with the higher-order node (closer to the root) first, and the downtree node (closer to the leaves) as the second argument. The segment from this node's parent to this node itself is not included. The order in which the segments are visited is depth-first.

Parameters
visitorA function to execute for every branch in the node's sub- tree.
69{
70 for (const auto& node : m_children) {
71 assert(node->m_parent.lock() == shared_from_this());
72 visitor(m_p, node->m_p);
73 node->visitBranches(visitor);
74 }
75}

References m_children, and m_p.

◆ visitNodes()

void Slic3r::FillLightning::Node::visitNodes ( const std::function< void(NodeSPtr)> &  visitor)

Execute a given function for every node in this node's sub-tree.

The visitor function takes a node as input. This node is not const, so this can be used to change the tree. Nodes are visited in depth-first order. This node itself is visited as well (pre-order).

Parameters
visitorA function to execute for every node in this node's sub- tree.
79{
80 visitor(shared_from_this());
81 for (const auto& node : m_children) {
82 assert(node->m_parent.lock() == shared_from_this());
83 node->visitNodes(visitor);
84 }
85}

References m_children.

Friends And Related Symbol Documentation

◆ get_extents [1/2]

BoundingBox get_extents ( const NodeSPtr root_node)
friend
285{
286 BoundingBox bbox;
287 for (const NodeSPtr &children : root_node->m_children)
288 bbox.merge(get_extents(children));
289 bbox.merge(root_node->getLocation());
290 return bbox;
291}
friend BoundingBox get_extents(const NodeSPtr &root_node)
Definition TreeNode.hpp:284
TMultiShape< PolygonImpl > merge(const TMultiShape< PolygonImpl > &shapes)
Definition geometries.hpp:259

◆ get_extents [2/2]

BoundingBox get_extents ( const std::vector< NodeSPtr > &  tree_roots)
friend
294{
295 BoundingBox bbox;
296 for (const NodeSPtr &root_node : tree_roots)
297 bbox.merge(get_extents(root_node));
298 return bbox;
299}

Member Data Documentation

◆ m_children

std::vector<NodeSPtr> Slic3r::FillLightning::Node::m_children
protected

◆ m_is_root

bool Slic3r::FillLightning::Node::m_is_root
protected

◆ m_last_grounding_location

std::optional<Point> Slic3r::FillLightning::Node::m_last_grounding_location
protected

◆ m_p

Point Slic3r::FillLightning::Node::m_p
protected

◆ m_parent

std::weak_ptr<Node> Slic3r::FillLightning::Node::m_parent
protected

Referenced by reroot().


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