Skip to content

Commit

Permalink
Move number of support functions to the edges & nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
nallath committed May 7, 2020
1 parent dfb4331 commit fe8551f
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 156 deletions.
138 changes: 9 additions & 129 deletions src/SkeletalTrapezoidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,14 +535,13 @@ void SkeletalTrapezoidation::filterMarking(coord_t max_length)
{
for (edge_t& edge : graph.edges)
{
if (isEndOfMarking(edge) && !isLocalMaximum(*edge.to) && !isLocalMaximum(*edge.to))
if (isEndOfMarking(edge) && edge.to->isLocalMaximum() && !edge.to->isLocalMaximum())
{
filterMarking(edge.twin, 0, max_length);
}
}
}


bool SkeletalTrapezoidation::filterMarking(edge_t* starting_edge, coord_t traveled_dist, coord_t max_length)
{
coord_t length = vSize(starting_edge->from->p - starting_edge->to->p);
Expand All @@ -560,7 +559,7 @@ bool SkeletalTrapezoidation::filterMarking(edge_t* starting_edge, coord_t travel
}
}

should_dissolve &= !isLocalMaximum(*starting_edge->to); // Don't filter marked regions with a local maximum!
should_dissolve &= !starting_edge->to->isLocalMaximum(); // Don't filter marked regions with a local maximum!
if (should_dissolve)
{
starting_edge->data.setMarked(false);
Expand Down Expand Up @@ -594,7 +593,7 @@ void SkeletalTrapezoidation::updateBeadCount()
// Fix bead count at locally maximal R, also for marked regions!! See TODO s in generateTransitionEnd(.)
for (node_t& node : graph.nodes)
{
if (isLocalMaximum(node))
if (node.isLocalMaximum())
{
if (node.data.distance_to_boundary < 0)
{
Expand Down Expand Up @@ -857,7 +856,7 @@ std::list<SkeletalTrapezoidation::TransitionMidRef> SkeletalTrapezoidation::diss
Point b = edge->to->p;
Point ab = b - a;
coord_t ab_size = vSize(ab);
bool is_aligned = isUpward(edge);
bool is_aligned = edge->isUpward();
edge_t* aligned_edge = is_aligned? edge : edge->twin;
bool seen_transition_on_this_edge = false;
auto edge_transitions_it = edge_to_transitions.find(aligned_edge);
Expand Down Expand Up @@ -1067,7 +1066,7 @@ bool SkeletalTrapezoidation::generateTransitionEnd(edge_t& edge, coord_t start_p
bool is_lower_end = end_rest == 0; // TODO collapse this parameter into the bool for which it is used here!
std::list<TransitionEnd>* transitions = nullptr;
coord_t pos = -1;
if (isUpward(&edge))
if (edge.isUpward())
{
transitions = &edge_to_transition_ends[&edge];
pos = end_pos;
Expand Down Expand Up @@ -1229,125 +1228,6 @@ bool SkeletalTrapezoidation::isEndOfMarking(const edge_t& edge_to) const
return true;
}

bool SkeletalTrapezoidation::isLocalMaximum(const node_t& node, bool strict) const
{
if (node.data.distance_to_boundary == 0)
{
return false;
}

bool first = true;
for (edge_t* edge = node.some_edge; first || edge != node.some_edge; edge = edge->twin->next)
{
if (canGoUp(edge, strict))
{
return false;
}
first = false;
assert(edge->twin); if (!edge->twin) return false;

if (!edge->twin->next)
{ // This point is on the boundary
return false;
}
}
return true;
}

bool SkeletalTrapezoidation::canGoUp(const edge_t* edge, bool strict) const
{
if (edge->to->data.distance_to_boundary > edge->from->data.distance_to_boundary)
{
return true;
}
if (edge->to->data.distance_to_boundary < edge->from->data.distance_to_boundary
|| strict
)
{
return false;
}

// Edge is between equidistqant verts; recurse!
for (edge_t* outgoing = edge->next; outgoing != edge->twin; outgoing = outgoing->twin->next)
{
if (canGoUp(outgoing))
{
return true;
}
assert(outgoing->twin); if (!outgoing->twin) return false;
assert(outgoing->twin->next); if (!outgoing->twin->next) return true; // This point is on the boundary?! Should never occur
}
return false;
}

std::optional<coord_t> SkeletalTrapezoidation::distToGoUp(const edge_t* edge) const
{
if (edge->to->data.distance_to_boundary > edge->from->data.distance_to_boundary)
{
return 0;
}
if (edge->to->data.distance_to_boundary < edge->from->data.distance_to_boundary)
{
return std::optional<coord_t>();
}

// Edge is between equidistqant verts; recurse!
std::optional<coord_t> ret;
for (edge_t* outgoing = edge->next; outgoing != edge->twin; outgoing = outgoing->twin->next)
{
std::optional<coord_t> dist_to_up = distToGoUp(outgoing);
if (dist_to_up)
{
if (ret)
{
ret = std::min(*ret, *dist_to_up);
}
else
{
ret = dist_to_up;
}
}
assert(outgoing->twin); if (!outgoing->twin) return std::optional<coord_t>();
assert(outgoing->twin->next); if (!outgoing->twin->next) return 0; // This point is on the boundary?! Should never occur
}
if (ret)
{
ret = *ret + vSize(edge->to->p - edge->from->p);
}
return ret;
}

bool SkeletalTrapezoidation::isUpward(const edge_t* edge) const
{
if (edge->to->data.distance_to_boundary > edge->from->data.distance_to_boundary)
{
return true;
}
if (edge->to->data.distance_to_boundary < edge->from->data.distance_to_boundary)
{
return false;
}
// Equidistant edge case:
std::optional<coord_t> forward_up_dist = distToGoUp(edge);
std::optional<coord_t> backward_up_dist = distToGoUp(edge->twin);
if (forward_up_dist && backward_up_dist)
{
return forward_up_dist < backward_up_dist;
}

if (forward_up_dist)
{
return true;
}

if (backward_up_dist)
{
return false;
}
return edge->to->p < edge->from->p; // Arbitrary ordering, which returns the opposite for the twin edge
}


void SkeletalTrapezoidation::generateExtraRibs()
{
auto end_edge_it = --graph.edges.end(); // Don't check newly introduced edges
Expand Down Expand Up @@ -1428,7 +1308,7 @@ void SkeletalTrapezoidation::generateSegments(std::vector<std::list<ExtrusionLin
std::vector<edge_t*> upward_quad_mids;
for (edge_t& edge : graph.edges)
{
if (edge.prev && edge.next && isUpward(&edge))
if (edge.prev && edge.next && edge.isUpward())
{
upward_quad_mids.emplace_back(&edge);
}
Expand All @@ -1442,8 +1322,8 @@ void SkeletalTrapezoidation::generateSegments(std::vector<std::list<ExtrusionLin
&& b->from->data.distance_to_boundary == b->to->data.distance_to_boundary)
{
coord_t max = std::numeric_limits<coord_t>::max();
coord_t a_dist_from_up = std::min(distToGoUp(a).value_or(max), distToGoUp(a->twin).value_or(max)) - vSize(a->to->p - a->from->p);
coord_t b_dist_from_up = std::min(distToGoUp(b).value_or(max), distToGoUp(b->twin).value_or(max)) - vSize(b->to->p - b->from->p);
coord_t a_dist_from_up = std::min(a->distToGoUp().value_or(max), a->twin->distToGoUp().value_or(max)) - vSize(a->to->p - a->from->p);
coord_t b_dist_from_up = std::min(b->distToGoUp().value_or(max), b->twin->distToGoUp().value_or(max)) - vSize(b->to->p - b->from->p);
return a_dist_from_up < b_dist_from_up;
}
else if (a->from->data.distance_to_boundary == a->to->data.distance_to_boundary)
Expand Down Expand Up @@ -1952,7 +1832,7 @@ void SkeletalTrapezoidation::generateLocalMaximaSingleBeads(std::unordered_map<n
{
node_t* node = pair.first;
Beading& beading = pair.second.beading;
if (beading.bead_widths.size() % 2 == 1 && isLocalMaximum(*node, true) && !node->isMarked())
if (beading.bead_widths.size() % 2 == 1 && node->isLocalMaximum(true) && !node->isMarked())
{
size_t inset_index = beading.bead_widths.size() / 2;
bool is_odd = true;
Expand Down
27 changes: 0 additions & 27 deletions src/SkeletalTrapezoidation.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,33 +265,6 @@ class SkeletalTrapezoidation

bool isEndOfMarking(const edge_t& edge) const;

/*!
* Check whether this node has a locally maximal distance_to_boundary
*
* \param strict Whether equidistant edges can count as a local maximum
*/
bool isLocalMaximum(const node_t& node, bool strict = false) const;

/*!
* Check (recursively) whether there is any upward edge from the distance_to_boundary of the from of the \param edge
*
* \param strict Whether equidistant edges can count as a local maximum
*/
bool canGoUp(const edge_t* edge, bool strict = false) const;

/*!
* Calculate the traversed distance until we meet an upward edge.
* Useful for calling on edges between equidistant points.
*
* If we can go up then the distance includes the length of the \param edge
*/
std::optional<coord_t> distToGoUp(const edge_t* edge) const;

/*!
* Check whether the edge goes from a lower to a higher distance_to_boundary.
* Effectively deals with equidistant edges by looking beyond this edge.
*/
bool isUpward(const edge_t* edge) const;

void generateExtraRibs();

Expand Down
111 changes: 111 additions & 0 deletions src/utils/HalfEdge.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#define UTILS_HALF_EDGE_H

#include <forward_list>
#include "../utils/optional.h" // until the move to C++17
#include "../utils/IntPoint.h"
#include "Coord_t.h"

namespace arachne
{
Expand Down Expand Up @@ -32,6 +35,114 @@ class HalfEdge
{
return this == &other;
}

/*!
* Check (recursively) whether there is any upward edge from the distance_to_boundary of the from of the \param edge
*
* \param strict Whether equidistant edges can count as a local maximum
*/
bool canGoUp(bool strict = false) const
{
if (to->data.distance_to_boundary > from->data.distance_to_boundary)
{
return true;
}
if (to->data.distance_to_boundary < from->data.distance_to_boundary || strict)
{
return false;
}

// Edge is between equidistqant verts; recurse!
for (edge_t* outgoing = next; outgoing != twin; outgoing = outgoing->twin->next)
{
if (outgoing->canGoUp())
{
return true;
}
assert(outgoing->twin); if (!outgoing->twin) return false;
assert(outgoing->twin->next); if (!outgoing->twin->next) return true; // This point is on the boundary?! Should never occur
}
return false;
}

/*!
* Check whether the edge goes from a lower to a higher distance_to_boundary.
* Effectively deals with equidistant edges by looking beyond this edge.
*/
bool isUpward() const
{
if (to->data.distance_to_boundary > from->data.distance_to_boundary)
{
return true;
}
if (to->data.distance_to_boundary < from->data.distance_to_boundary)
{
return false;
}

// Equidistant edge case:
std::optional<cura::coord_t> forward_up_dist = this->distToGoUp();
std::optional<cura::coord_t> backward_up_dist = twin->distToGoUp();
if (forward_up_dist && backward_up_dist)
{
return forward_up_dist < backward_up_dist;
}

if (forward_up_dist)
{
return true;
}

if (backward_up_dist)
{
return false;
}
return to->p < from->p; // Arbitrary ordering, which returns the opposite for the twin edge
}


/*!
* Calculate the traversed distance until we meet an upward edge.
* Useful for calling on edges between equidistant points.
*
* If we can go up then the distance includes the length of the \param edge
*/
std::optional<cura::coord_t> distToGoUp() const
{
if (to->data.distance_to_boundary > from->data.distance_to_boundary)
{
return 0;
}
if (to->data.distance_to_boundary < from->data.distance_to_boundary)
{
return std::optional<cura::coord_t>();
}

// Edge is between equidistqant verts; recurse!
std::optional<cura::coord_t> ret;
for (edge_t* outgoing = next; outgoing != twin; outgoing = outgoing->twin->next)
{
std::optional<cura::coord_t> dist_to_up = outgoing->distToGoUp();
if (dist_to_up)
{
if (ret)
{
ret = std::min(*ret, *dist_to_up);
}
else
{
ret = dist_to_up;
}
}
assert(outgoing->twin); if (!outgoing->twin) return std::optional<cura::coord_t>();
assert(outgoing->twin->next); if (!outgoing->twin->next) return 0; // This point is on the boundary?! Should never occur
}
if (ret)
{
ret = *ret + cura::vSize(to->p - from->p);
}
return ret;
}
};


Expand Down
Loading

0 comments on commit fe8551f

Please sign in to comment.