mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-07-31 12:52:01 +08:00
add minimal width to edge
Fix creation of Field and sampling outline
This commit is contained in:
parent
0033deb1d4
commit
f44b0d51f1
@ -28,7 +28,7 @@ void ExpandNeighbor::process(CallStack &call_stack)
|
||||
const VoronoiGraph::Node &next_node = *neighbor.node;
|
||||
// is next node leaf ?
|
||||
if (next_node.neighbors.size() == 1) {
|
||||
VoronoiGraph::Path side_branch({&next_node}, neighbor.edge_length);
|
||||
VoronoiGraph::Path side_branch({&next_node}, neighbor.length());
|
||||
data.side_branches.push(std::move(side_branch));
|
||||
return;
|
||||
}
|
||||
@ -39,6 +39,6 @@ void ExpandNeighbor::process(CallStack &call_stack)
|
||||
call_stack.emplace(std::move(post_process_neighbor));
|
||||
call_stack.emplace(
|
||||
std::make_unique<EvaluateNeighbor>(neighbor_path, neighbor.node,
|
||||
neighbor.edge_length,
|
||||
neighbor.length(),
|
||||
data.act_path));
|
||||
}
|
@ -72,6 +72,30 @@ bool ParabolaUtils::is_over_zero(const ParabolaSegment ¶bola)
|
||||
return is_positive_x1 != is_positive_x2;
|
||||
}
|
||||
|
||||
void ParabolaUtils::draw(SVG & svg,
|
||||
const ParabolaSegment ¶bola,
|
||||
const char * color,
|
||||
coord_t width,
|
||||
double discretization_step)
|
||||
{
|
||||
using VD = Slic3r::Geometry::VoronoiDiagram;
|
||||
std::vector<Voronoi::Internal::point_type> parabola_samples(
|
||||
{parabola.from, parabola.to});
|
||||
|
||||
VD::point_type source_point = parabola.focus;
|
||||
VD::segment_type source_segment(parabola.directrix.a,
|
||||
parabola.directrix.b);
|
||||
::boost::polygon::voronoi_visual_utils<double>::discretize(
|
||||
source_point, source_segment, discretization_step, ¶bola_samples);
|
||||
|
||||
for (size_t index = 1; index < parabola_samples.size(); ++index) {
|
||||
const auto& s0 = parabola_samples[index - 1];
|
||||
const auto& s1 = parabola_samples[index];
|
||||
Line l(Point(s0.x(), s0.y()), Point(s1.x(), s1.y()));
|
||||
svg.draw(l, color, width);
|
||||
}
|
||||
}
|
||||
|
||||
// PRIVATE
|
||||
double ParabolaUtils::parabola_arc_length(double x)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define slic3r_SLA_SuppotstIslands_ParabolaUtils_hpp_
|
||||
|
||||
#include "Parabola.hpp"
|
||||
#include <libslic3r/SVG.hpp>
|
||||
|
||||
namespace Slic3r::sla {
|
||||
|
||||
@ -44,6 +45,20 @@ public:
|
||||
/// <returns>True when interval contain top of parabola otherwise False</returns>
|
||||
static bool is_over_zero(const ParabolaSegment ¶bola);
|
||||
|
||||
/// <summary>
|
||||
/// Connvert parabola to svg by sampling
|
||||
/// </summary>
|
||||
/// <param name="svg">outputfile</param>
|
||||
/// <param name="parabola">parabola to draw</param>
|
||||
/// <param name="color">color</param>
|
||||
/// <param name="width">width</param>
|
||||
/// <param name="discretization_step">step between discretized lines</param>
|
||||
static void draw(SVG & svg,
|
||||
const ParabolaSegment ¶bola,
|
||||
const char * color,
|
||||
coord_t width,
|
||||
double discretization_step = 1e3);
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
/// Integral of parabola: y = x^2 from zero to point x
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <libslic3r/ClipperUtils.hpp> // allign
|
||||
|
||||
// comment definition of NDEBUG to enable assert()
|
||||
// #define NDEBUG
|
||||
//#define NDEBUG
|
||||
|
||||
#define SLA_SAMPLING_STORE_FIELD_TO_SVG
|
||||
#define SLA_SAMPLING_STORE_VORONOI_GRAPH_TO_SVG
|
||||
@ -50,11 +50,11 @@ std::unique_ptr<SupportIslandPoint> SampleIslandUtils::create_point_on_path(
|
||||
}
|
||||
const VoronoiGraph::Node::Neighbor *neighbor =
|
||||
VoronoiGraphUtils::get_neighbor(prev_node, node);
|
||||
actual_distance += neighbor->edge_length;
|
||||
actual_distance += neighbor->length();
|
||||
if (actual_distance >= distance) {
|
||||
// over half point is on
|
||||
double previous_distance = actual_distance - distance;
|
||||
double over_ratio = previous_distance / neighbor->edge_length;
|
||||
double over_ratio = previous_distance / neighbor->length();
|
||||
double ratio = 1. - over_ratio;
|
||||
return create_point(neighbor, ratio, type);
|
||||
}
|
||||
@ -126,14 +126,14 @@ SupportIslandPoints SampleIslandUtils::sample_side_branch(
|
||||
std::move_iterator(side_samples.end()));
|
||||
}
|
||||
}
|
||||
while (distance < neighbor->edge_length) {
|
||||
double edge_ratio = distance / neighbor->edge_length;
|
||||
while (distance < neighbor->length()) {
|
||||
double edge_ratio = distance / neighbor->length();
|
||||
result.push_back(
|
||||
create_point(neighbor, edge_ratio, SupportIslandPoint::Type::center_line)
|
||||
);
|
||||
distance += sample_distance;
|
||||
}
|
||||
distance -= neighbor->edge_length;
|
||||
distance -= neighbor->length();
|
||||
prev_node = node;
|
||||
}
|
||||
assert(fabs(distance - (sample_distance - cfg.side_distance)) < 1e-5);
|
||||
@ -310,12 +310,12 @@ void SampleIslandUtils::sample_center_circle_end(
|
||||
const CenterLineConfiguration & cfg,
|
||||
SupportIslandPoints & result)
|
||||
{
|
||||
double distance = neighbor_distance + node_distance + neighbor.edge_length;
|
||||
double distance = neighbor_distance + node_distance + neighbor.length();
|
||||
if (distance < cfg.max_sample_distance) { // no need add support point
|
||||
if (neighbor_distance > node_distance + neighbor.edge_length)
|
||||
neighbor_distance = node_distance + neighbor.edge_length;
|
||||
if (node_distance > neighbor_distance + neighbor.edge_length)
|
||||
node_distance = neighbor_distance + neighbor.edge_length;
|
||||
if (neighbor_distance > node_distance + neighbor.length())
|
||||
neighbor_distance = node_distance + neighbor.length();
|
||||
if (node_distance > neighbor_distance + neighbor.length())
|
||||
node_distance = neighbor_distance + neighbor.length();
|
||||
return;
|
||||
}
|
||||
size_t count_supports = static_cast<size_t>(
|
||||
@ -328,11 +328,11 @@ void SampleIslandUtils::sample_center_circle_end(
|
||||
neighbor_distance = 0.;
|
||||
count_supports -= 1;
|
||||
if (count_supports == 0) {
|
||||
if (node_distance > neighbor.edge_length)
|
||||
node_distance = neighbor.edge_length;
|
||||
if (node_distance > neighbor.length())
|
||||
node_distance = neighbor.length();
|
||||
return;
|
||||
}
|
||||
distance = node_distance + neighbor.edge_length;
|
||||
distance = node_distance + neighbor.length();
|
||||
distance_between = distance / (count_supports + 1);
|
||||
}
|
||||
VoronoiGraph::Nodes nodes = done_nodes; // copy, could be more neighbor
|
||||
@ -341,7 +341,7 @@ void SampleIslandUtils::sample_center_circle_end(
|
||||
double distance_from_neighbor = i * (distance_between) - neighbor_distance;
|
||||
result.push_back(
|
||||
create_point_on_path(nodes, distance_from_neighbor, SupportIslandPoint::Type::center_circle_end2));
|
||||
double distance_support_to_node = fabs(neighbor.edge_length -
|
||||
double distance_support_to_node = fabs(neighbor.length() -
|
||||
distance_from_neighbor);
|
||||
if (node_distance > distance_support_to_node)
|
||||
node_distance = distance_support_to_node;
|
||||
@ -396,7 +396,7 @@ double get_distance_to_support_point(const VoronoiGraph::Node *node,
|
||||
};
|
||||
std::priority_queue<Item, std::vector<Item>, OrderDistanceFromNearest> process;
|
||||
for (const VoronoiGraph::Node::Neighbor &neighbor : node->neighbors)
|
||||
process.emplace(node, neighbor.node, neighbor.edge_length);
|
||||
process.emplace(node, neighbor.node, neighbor.length());
|
||||
|
||||
while (!process.empty()) {
|
||||
Item i = process.top();
|
||||
@ -411,7 +411,7 @@ double get_distance_to_support_point(const VoronoiGraph::Node *node,
|
||||
}
|
||||
for (const VoronoiGraph::Node::Neighbor &neighbor :i.node->neighbors) {
|
||||
if (neighbor.node == i.prev_node) continue;
|
||||
double distance = i.act_distance + neighbor.edge_length;
|
||||
double distance = i.act_distance + neighbor.length();
|
||||
if (distance > maximal_search) continue;
|
||||
process.emplace(i.node, neighbor.node, distance);
|
||||
}
|
||||
@ -443,8 +443,8 @@ SupportDistanceMap create_support_distance_map(const SupportIslandPoints &suppor
|
||||
const VoronoiGraph::Position &position = ptr->position;
|
||||
const VoronoiGraph::Node *node = position.neighbor->node;
|
||||
const VoronoiGraph::Node *twin_node = VoronoiGraphUtils::get_twin_node(position.neighbor);
|
||||
double distance = (1 - position.ratio) * position.neighbor->edge_length;
|
||||
double twin_distance = position.ratio * position.neighbor->edge_length;
|
||||
double distance = (1 - position.ratio) * position.neighbor->length();
|
||||
double twin_distance = position.ratio * position.neighbor->length();
|
||||
|
||||
auto item = support_distance_map.find(node);
|
||||
if (item == support_distance_map.end()) {
|
||||
@ -584,14 +584,14 @@ SupportIslandPoints SampleIslandUtils::sample_center_circle(
|
||||
|
||||
NodeDistance next_nd = nd; // copy
|
||||
next_nd.nodes.insert(next_nd.nodes.begin(), neighbor.node);
|
||||
next_nd.distance_from_support_point += neighbor.edge_length;
|
||||
next_nd.distance_from_support_point += neighbor.length();
|
||||
// exist place for sample:
|
||||
while (next_nd.distance_from_support_point >
|
||||
cfg.max_sample_distance) {
|
||||
double distance_from_node = next_nd
|
||||
.distance_from_support_point -
|
||||
nd.distance_from_support_point;
|
||||
double ratio = distance_from_node / neighbor.edge_length;
|
||||
double ratio = distance_from_node / neighbor.length();
|
||||
result.push_back(
|
||||
create_point(&neighbor, ratio, SupportIslandPoint::Type::center_circle));
|
||||
next_nd.distance_from_support_point -= cfg.max_sample_distance;
|
||||
@ -602,20 +602,28 @@ SupportIslandPoints SampleIslandUtils::sample_center_circle(
|
||||
return result;
|
||||
}
|
||||
|
||||
void SampleIslandUtils::sample_field(
|
||||
VoronoiGraph::Position& field_start,
|
||||
SupportIslandPoints& points,
|
||||
CenterStarts& center_starts,
|
||||
std::set<const VoronoiGraph::Node *>& done,
|
||||
const Lines & lines,
|
||||
const SampleConfig &config)
|
||||
SupportIslandPoints SampleIslandUtils::sample_voronoi_graph(
|
||||
const VoronoiGraph & graph,
|
||||
const Lines & lines,
|
||||
const SampleConfig & config,
|
||||
VoronoiGraph::ExPath &longest_path)
|
||||
{
|
||||
auto field = create_field(field_start, center_starts, done, lines, config);
|
||||
SupportIslandPoints outline_support = sample_outline(field, config);
|
||||
points.insert(points.end(), std::move_iterator(outline_support.begin()),
|
||||
std::move_iterator(outline_support.end()));
|
||||
// TODO: sample field inside
|
||||
const VoronoiGraph::Node *start_node =
|
||||
VoronoiGraphUtils::getFirstContourNode(graph);
|
||||
// every island has to have a point on contour
|
||||
assert(start_node != nullptr);
|
||||
longest_path = VoronoiGraphUtils::create_longest_path(start_node);
|
||||
// longest_path = create_longest_path_recursive(start_node);
|
||||
|
||||
#ifdef SLA_SAMPLING_STORE_VORONOI_GRAPH_TO_SVG
|
||||
{
|
||||
static int counter = 0;
|
||||
SVG svg("voronoiGraph" + std::to_string(counter++) + ".svg",
|
||||
LineUtils::create_bounding_box(lines));
|
||||
VoronoiGraphUtils::draw(svg, graph, lines, 1e6, true);
|
||||
}
|
||||
#endif // SLA_SAMPLING_STORE_VORONOI_GRAPH_TO_SVG
|
||||
return sample_expath(longest_path, lines, config);
|
||||
}
|
||||
|
||||
SupportIslandPoints SampleIslandUtils::sample_expath(
|
||||
@ -653,8 +661,7 @@ SupportIslandPoints SampleIslandUtils::sample_expath(
|
||||
// TODO: 3) Triangle of points
|
||||
// eval outline and find three point create almost equilateral triangle
|
||||
|
||||
// IMPROVE: Erase continous sampling: Extract path and than sample uniformly whole path
|
||||
|
||||
// IMPROVE: Erase continous sampling: Extract ExPath and than sample uniformly whole ExPath
|
||||
CenterStarts center_starts;
|
||||
const VoronoiGraph::Node *start_node = path.nodes.front();
|
||||
// CHECK> Front of path is outline node
|
||||
@ -662,26 +669,19 @@ SupportIslandPoints SampleIslandUtils::sample_expath(
|
||||
const VoronoiGraph::Node::Neighbor *neighbor = &start_node->neighbors.front();
|
||||
std::set<const VoronoiGraph::Node *> done; // already done nodes
|
||||
SupportIslandPoints points; // result
|
||||
if (neighbor->max_width > config.max_width_for_center_support_line) {
|
||||
VoronoiGraph::Position field_start = VoronoiGraphUtils::get_position_with_distance(
|
||||
neighbor, config.min_width_for_outline_support, lines);
|
||||
double center_sample_distance = neighbor->edge_length * field_start.ratio;
|
||||
if (center_sample_distance > config.max_distance / 2.) {
|
||||
// sample field from node, start without change on begining
|
||||
sample_field(field_start, points, center_starts, done, lines, config);
|
||||
} else {
|
||||
const VoronoiGraph::Node::Neighbor *twin = VoronoiGraphUtils::get_twin(neighbor);
|
||||
done.insert(neighbor->node);
|
||||
coord_t support_in = neighbor->edge_length - center_sample_distance +
|
||||
config.max_distance / 2;
|
||||
center_starts.push(CenterStart(twin, support_in, {neighbor->node}));
|
||||
sample_field(field_start, points, center_starts, done, lines, config);
|
||||
}
|
||||
} else {
|
||||
if (neighbor->max_width() < config.max_width_for_center_support_line) {
|
||||
// start sample center
|
||||
done.insert(start_node);
|
||||
center_starts.push(CenterStart(neighbor, config.minimal_distance_from_outline));
|
||||
coord_t support_in = config.minimal_distance_from_outline;
|
||||
center_starts.push(CenterStart(neighbor, support_in));
|
||||
} else {
|
||||
// start sample field
|
||||
VoronoiGraph::Position field_start =
|
||||
VoronoiGraphUtils::get_position_with_distance(
|
||||
neighbor, config.min_width_for_outline_support, lines);
|
||||
sample_field(field_start, points, center_starts, done, lines, config);
|
||||
}
|
||||
|
||||
// Main loop of sampling
|
||||
while (!center_starts.empty()) {
|
||||
std::optional<VoronoiGraph::Position> field_start = {};
|
||||
std::vector<CenterStart> new_starts =
|
||||
@ -693,10 +693,23 @@ SupportIslandPoints SampleIslandUtils::sample_expath(
|
||||
field_start = {};
|
||||
}
|
||||
}
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
void SampleIslandUtils::sample_field(VoronoiGraph::Position &field_start,
|
||||
SupportIslandPoints & points,
|
||||
CenterStarts & center_starts,
|
||||
std::set<const VoronoiGraph::Node *> &done,
|
||||
const Lines & lines,
|
||||
const SampleConfig &config)
|
||||
{
|
||||
auto field = create_field(field_start, center_starts, done, lines, config);
|
||||
SupportIslandPoints outline_support = sample_outline(field, config);
|
||||
points.insert(points.end(), std::move_iterator(outline_support.begin()),
|
||||
std::move_iterator(outline_support.end()));
|
||||
// TODO: sample field inside
|
||||
}
|
||||
|
||||
std::vector<SampleIslandUtils::CenterStart> SampleIslandUtils::sample_center(
|
||||
const CenterStart & start,
|
||||
const SampleConfig & config,
|
||||
@ -707,13 +720,13 @@ std::vector<SampleIslandUtils::CenterStart> SampleIslandUtils::sample_center(
|
||||
{
|
||||
const VoronoiGraph::Node::Neighbor *neighbor = start.neighbor;
|
||||
const VoronoiGraph::Node *node = neighbor->node;
|
||||
// already sampled line
|
||||
if (done.find(node) != done.end()) return {};
|
||||
done.insert(node);
|
||||
VoronoiGraph::Nodes path = start.path;
|
||||
std::vector<CenterStart> new_starts;
|
||||
double support_in = start.support_in;
|
||||
do {
|
||||
double edge_length = neighbor->edge_length;
|
||||
double edge_length = neighbor->length();
|
||||
while (edge_length >= support_in) {
|
||||
double ratio = support_in / edge_length;
|
||||
results.push_back(
|
||||
@ -724,6 +737,7 @@ std::vector<SampleIslandUtils::CenterStart> SampleIslandUtils::sample_center(
|
||||
support_in -= edge_length;
|
||||
const VoronoiGraph::Node *node = neighbor->node;
|
||||
path.push_back(node);
|
||||
done.insert(node);
|
||||
const VoronoiGraph::Node::Neighbor *next_neighbor = nullptr;
|
||||
for (const auto &node_neighbor : node->neighbors) {
|
||||
if (done.find(node_neighbor.node) != done.end()) continue;
|
||||
@ -754,11 +768,14 @@ std::vector<SampleIslandUtils::CenterStart> SampleIslandUtils::sample_center(
|
||||
} else {
|
||||
neighbor = next_neighbor;
|
||||
}
|
||||
} while (neighbor->max_width <= config.max_width_for_center_support_line);
|
||||
} while (neighbor->max_width() <= config.max_width_for_center_support_line);
|
||||
|
||||
// create field start
|
||||
field_start = VoronoiGraphUtils::get_position_with_distance(
|
||||
neighbor, config.min_width_for_outline_support, lines);
|
||||
double edge_length = neighbor->edge_length;
|
||||
|
||||
// sample rest of neighbor before field
|
||||
double edge_length = neighbor->length();
|
||||
double sample_length = edge_length * field_start->ratio;
|
||||
while (sample_length > support_in) {
|
||||
double ratio = support_in / edge_length;
|
||||
@ -769,29 +786,6 @@ std::vector<SampleIslandUtils::CenterStart> SampleIslandUtils::sample_center(
|
||||
return new_starts;
|
||||
}
|
||||
|
||||
SupportIslandPoints SampleIslandUtils::sample_voronoi_graph(
|
||||
const VoronoiGraph & graph,
|
||||
const Lines & lines,
|
||||
const SampleConfig & config,
|
||||
VoronoiGraph::ExPath &longest_path)
|
||||
{
|
||||
const VoronoiGraph::Node *start_node =
|
||||
VoronoiGraphUtils::getFirstContourNode(graph);
|
||||
// every island has to have a point on contour
|
||||
assert(start_node != nullptr);
|
||||
longest_path = VoronoiGraphUtils::create_longest_path(start_node);
|
||||
// longest_path = create_longest_path_recursive(start_node);
|
||||
|
||||
#ifdef SLA_SAMPLING_STORE_VORONOI_GRAPH_TO_SVG
|
||||
{
|
||||
static int counter=0;
|
||||
SVG svg("voronoiGraph"+std::to_string(counter++)+".svg", LineUtils::create_bounding_box(lines));
|
||||
LineUtils::draw(svg, lines, "black",0., true);
|
||||
VoronoiGraphUtils::draw(svg, graph, 1e6, true);
|
||||
}
|
||||
#endif // SLA_SAMPLING_STORE_VORONOI_GRAPH_TO_SVG
|
||||
return sample_expath(longest_path, lines, config);
|
||||
}
|
||||
|
||||
SampleIslandUtils::Field SampleIslandUtils::create_field(
|
||||
const VoronoiGraph::Position & field_start,
|
||||
@ -844,10 +838,11 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
|
||||
const VoronoiGraph::Node * source_node)->bool {
|
||||
const VoronoiGraph::Node::Neighbor *neighbor = position.neighbor;
|
||||
|
||||
// TODO: check not only one neighbor but all path to edge
|
||||
// IMPROVE: check not only one neighbor but all path to edge
|
||||
coord_t rest_size = static_cast<coord_t>(neighbor->length() * (1. - position.ratio));
|
||||
if (VoronoiGraphUtils::is_last_neighbor(neighbor) &&
|
||||
neighbor->edge_length * (1. - position.ratio) <= config.max_distance / 2)
|
||||
return false;
|
||||
rest_size <= config.max_distance / 2)
|
||||
return false; // no change only rich outline
|
||||
|
||||
// function to add sorted change from wide to tiny
|
||||
// stored uder line index or line shorten in point b
|
||||
@ -864,8 +859,7 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
|
||||
};
|
||||
|
||||
Point p1, p2;
|
||||
std::tie(p1, p2) = VoronoiGraphUtils::point_on_lines(position,
|
||||
lines);
|
||||
std::tie(p1, p2) = VoronoiGraphUtils::point_on_lines(position, lines);
|
||||
const VD::edge_type *edge = neighbor->edge;
|
||||
size_t i1 = edge->cell()->source_index();
|
||||
size_t i2 = edge->twin()->cell()->source_index();
|
||||
@ -879,7 +873,7 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
|
||||
// line1 is shorten on side line1.b
|
||||
add(p1, p2, i1, i2);
|
||||
}
|
||||
coord_t support_in = neighbor->edge_length * position.ratio + config.max_distance/2;
|
||||
coord_t support_in = neighbor->length() * position.ratio + config.max_distance/2;
|
||||
CenterStart tiny_start(neighbor, support_in, {source_node});
|
||||
tiny_starts.push(tiny_start);
|
||||
tiny_done.insert(source_node);
|
||||
@ -893,14 +887,16 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
|
||||
|
||||
std::set<const VoronoiGraph::Node*> done;
|
||||
done.insert(twin_neighbor->node);
|
||||
std::queue<const VoronoiGraph::Node *> process;
|
||||
process.push(neighbor->node);
|
||||
using ProcessItem = std::pair<const VoronoiGraph::Node *, const VoronoiGraph::Node *>;
|
||||
std::queue<ProcessItem> process;
|
||||
process.push({twin_neighbor->node, neighbor->node});
|
||||
|
||||
// all lines belongs to polygon
|
||||
std::set<size_t> field_line_indexes;
|
||||
while (!process.empty()) {
|
||||
const VoronoiGraph::Node *node = process.front();
|
||||
const VoronoiGraph::Node *prev_node = nullptr;
|
||||
const ProcessItem &item = process.front();
|
||||
const VoronoiGraph::Node *node = item.second;
|
||||
const VoronoiGraph::Node *prev_node = item.first;
|
||||
process.pop();
|
||||
if (done.find(node) != done.end()) continue;
|
||||
do {
|
||||
@ -913,7 +909,7 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
|
||||
size_t index2 = edge->twin()->cell()->source_index();
|
||||
field_line_indexes.insert(index1);
|
||||
field_line_indexes.insert(index2);
|
||||
if (VoronoiGraphUtils::is_last_neighbor(&neighbor) || neighbor.max_width < min_width) {
|
||||
if (neighbor.min_width() < min_width) {
|
||||
VoronoiGraph::Position position =
|
||||
VoronoiGraphUtils::get_position_with_distance(&neighbor, min_width, lines);
|
||||
if(add_wide_tiny_change(position, node))
|
||||
@ -923,7 +919,7 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
|
||||
if (next_node == nullptr) {
|
||||
next_node = neighbor.node;
|
||||
} else {
|
||||
process.push(neighbor.node);
|
||||
process.push({node, neighbor.node});
|
||||
}
|
||||
}
|
||||
prev_node = node;
|
||||
@ -996,7 +992,9 @@ SampleIslandUtils::Field SampleIslandUtils::create_field(
|
||||
points.reserve(field_line_indexes.size());
|
||||
std::vector<size_t> outline_indexes;
|
||||
outline_indexes.reserve(field_line_indexes.size());
|
||||
size_t input_index = neighbor->edge->cell()->source_index();
|
||||
size_t input_index1 = neighbor->edge->cell()->source_index();
|
||||
size_t input_index2 = neighbor->edge->twin()->cell()->source_index();
|
||||
size_t input_index = std::min(input_index1, input_index2);
|
||||
size_t outline_index = input_index;
|
||||
std::set<size_t> done_indexes;
|
||||
do {
|
||||
|
@ -108,17 +108,6 @@ public:
|
||||
const CenterLineConfiguration & cfg,
|
||||
SupportIslandPoints & result);
|
||||
|
||||
/// <summary>
|
||||
/// Decide how to sample path
|
||||
/// </summary>
|
||||
/// <param name="path">Path inside voronoi diagram with side branches and circles</param>
|
||||
/// <param name="lines">Source lines for VG --> outline of island.</param>
|
||||
/// <param name="config">Definition how to sample</param>
|
||||
/// <returns>Support points for island</returns>
|
||||
static SupportIslandPoints sample_expath(const VoronoiGraph::ExPath &path,
|
||||
const Lines & lines,
|
||||
const SampleConfig &config);
|
||||
|
||||
/// <summary>
|
||||
/// Sample voronoi skeleton
|
||||
/// </summary>
|
||||
@ -134,6 +123,18 @@ public:
|
||||
const SampleConfig & config,
|
||||
VoronoiGraph::ExPath &longest_path);
|
||||
|
||||
/// <summary>
|
||||
/// Decide how to sample path
|
||||
/// </summary>
|
||||
/// <param name="path">Path inside voronoi diagram with side branches and circles</param>
|
||||
/// <param name="lines">Source lines for VG --> outline of island.</param>
|
||||
/// <param name="config">Definition how to sample</param>
|
||||
/// <returns>Support points for island</returns>
|
||||
static SupportIslandPoints sample_expath(const VoronoiGraph::ExPath &path,
|
||||
const Lines & lines,
|
||||
const SampleConfig &config);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Transform support point to slicer points
|
||||
/// </summary>
|
||||
@ -250,9 +251,9 @@ public:
|
||||
/// <summary>
|
||||
/// Create field from input neighbor
|
||||
/// </summary>
|
||||
/// <param name="field_start">Start neighbor, first occur of wide neighbor.</param>
|
||||
/// <param name="field_start">Start position, change from tiny to wide.</param>
|
||||
/// <param name="tiny_starts">Append new founded tiny parts of island.</param>
|
||||
/// <param name="tiny_done">Already sampled node sets. Filled only node inside field imediate after change</param>
|
||||
/// <param name="tiny_done">Already sampled node sets.</param>
|
||||
/// <param name="lines">Source lines for VG --> outline of island.</param>
|
||||
/// <param name="config">Containe Minimal width in field and sample distance for center line</param>
|
||||
/// <returns>New created field</returns>
|
||||
|
@ -57,23 +57,40 @@ struct VoronoiGraph::Node::Neighbor
|
||||
const VD::edge_type *edge;
|
||||
// pointer on graph node structure
|
||||
const Node *node;
|
||||
|
||||
/// <summary>
|
||||
/// DTO represents size property of one Neighbor
|
||||
/// </summary>
|
||||
struct Size{
|
||||
// length edge between vertices
|
||||
double length;
|
||||
|
||||
// length edge between vertices
|
||||
double edge_length;
|
||||
// widht is distance between outlines
|
||||
// maximal width
|
||||
coord_t min_width;
|
||||
// minimal widht
|
||||
coord_t max_width;
|
||||
|
||||
// maximal widht of sland(distance to outline)
|
||||
double max_width;
|
||||
Size(double length, coord_t min_width, coord_t max_width)
|
||||
: length(length), min_width(min_width), max_width(max_width)
|
||||
{}
|
||||
};
|
||||
std::shared_ptr<Size> size;
|
||||
|
||||
public:
|
||||
Neighbor(const VD::edge_type *edge, const Node *node, double edge_length, double max_width)
|
||||
Neighbor(const VD::edge_type * edge,
|
||||
const Node * node,
|
||||
std::shared_ptr<Size> size)
|
||||
: edge(edge)
|
||||
, node(node)
|
||||
, edge_length(edge_length)
|
||||
, max_width(max_width)
|
||||
, size(std::move(size))
|
||||
{}
|
||||
// accessor to member
|
||||
double length() const { return size->length; }
|
||||
coord_t min_width() const { return size->min_width; }
|
||||
coord_t max_width() const { return size->max_width; }
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DTO represents path over nodes of VoronoiGraph
|
||||
/// store queue of Nodes
|
||||
|
@ -423,6 +423,79 @@ double VoronoiGraphUtils::calculate_max_width(
|
||||
return max_width(parabola.focus);
|
||||
}
|
||||
|
||||
std::pair<coord_t, coord_t> VoronoiGraphUtils::calculate_width(
|
||||
const VD::edge_type &edge, const Lines &lines)
|
||||
{
|
||||
if (edge.is_linear())
|
||||
return calculate_width_for_line(edge, lines);
|
||||
return calculate_width_for_parabola(edge, lines);
|
||||
}
|
||||
|
||||
std::pair<coord_t, coord_t> VoronoiGraphUtils::calculate_width_for_line(
|
||||
const VD::edge_type &line_edge, const Lines &lines)
|
||||
{
|
||||
assert(line_edge.is_linear());
|
||||
// edge line could be initialized by 2 points
|
||||
if (line_edge.cell()->contains_point()) {
|
||||
const Line &source_line = lines[line_edge.cell()->source_index()];
|
||||
Point source_point;
|
||||
if (line_edge.cell()->source_category() ==
|
||||
boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT)
|
||||
source_point = source_line.a;
|
||||
else {
|
||||
assert(line_edge.cell()->source_category() ==
|
||||
boost::polygon::SOURCE_CATEGORY_SEGMENT_END_POINT);
|
||||
source_point = source_line.b;
|
||||
}
|
||||
return min_max_width(line_edge, source_point);
|
||||
}
|
||||
assert(line_edge.cell()->contains_segment());
|
||||
assert(!line_edge.twin()->cell()->contains_point());
|
||||
assert(line_edge.twin()->cell()->contains_segment());
|
||||
const Line & line = lines[line_edge.cell()->source_index()];
|
||||
Point v0 = to_point(line_edge.vertex0());
|
||||
Point v1 = to_point(line_edge.vertex1());
|
||||
double distance0 = line.perp_distance_to(v0);
|
||||
double distance1 = line.perp_distance_to(v1);
|
||||
std::pair<coord_t, coord_t> min_max(2 * static_cast<coord_t>(distance0),
|
||||
2 * static_cast<coord_t>(distance1));
|
||||
if (min_max.first > min_max.second)
|
||||
std::swap(min_max.first, min_max.second);
|
||||
return min_max;
|
||||
}
|
||||
|
||||
std::pair<coord_t, coord_t> VoronoiGraphUtils::calculate_width_for_parabola(
|
||||
const VD::edge_type ¶bola_edge, const Lines &lines)
|
||||
{
|
||||
assert(parabola_edge.is_curved());
|
||||
// distance to point and line on parabola is same
|
||||
Parabola parabola = get_parabola(parabola_edge, lines);
|
||||
Point v0 = to_point(parabola_edge.vertex0());
|
||||
Point v1 = to_point(parabola_edge.vertex1());
|
||||
ParabolaSegment parabola_segment(parabola, v0, v1);
|
||||
std::pair<coord_t, coord_t> min_max = min_max_width(parabola_edge, parabola.focus);
|
||||
if (ParabolaUtils::is_over_zero(parabola_segment)) {
|
||||
min_max.first = parabola.directrix.perp_distance_to(parabola.focus);
|
||||
}
|
||||
return min_max;
|
||||
}
|
||||
|
||||
std::pair<coord_t, coord_t> VoronoiGraphUtils::min_max_width(
|
||||
const VD::edge_type &edge, const Point &point)
|
||||
{
|
||||
auto distance = [](const VD::vertex_type *vertex,
|
||||
const Point & point) -> coord_t {
|
||||
Vec2d point_d = point.cast<double>();
|
||||
Vec2d diff = point_d - to_point_d(vertex);
|
||||
double distance = diff.norm();
|
||||
return static_cast<coord_t>(std::round(distance));
|
||||
};
|
||||
std::pair<coord_t, coord_t> result(2 * distance(edge.vertex0(), point),
|
||||
2 * distance(edge.vertex1(), point));
|
||||
if (result.first > result.second) std::swap(result.first, result.second);
|
||||
return result;
|
||||
};
|
||||
|
||||
VoronoiGraph VoronoiGraphUtils::create_skeleton(const VD &vd, const Lines &lines)
|
||||
{
|
||||
// vd should be annotated.
|
||||
@ -458,16 +531,16 @@ VoronoiGraph VoronoiGraphUtils::create_skeleton(const VD &vd, const Lines &lines
|
||||
return {}; // vd must be annotated
|
||||
|
||||
double length = calculate_length(edge, lines);
|
||||
double max_width = calculate_max_width(edge, lines);
|
||||
coord_t min_width, max_width;
|
||||
std::tie(min_width, max_width) = calculate_width(edge, lines);
|
||||
auto neighbor_size = std::make_shared<VoronoiGraph::Node::Neighbor::Size>(
|
||||
length, min_width, max_width);
|
||||
|
||||
VoronoiGraph::Node *node0 = getNode(skeleton, v0, &edge, lines);
|
||||
VoronoiGraph::Node *node1 = getNode(skeleton, v1, &edge, lines);
|
||||
|
||||
// TODO: Do not store twice length and max_width.
|
||||
// add extended Edge to graph, both side
|
||||
VoronoiGraph::Node::Neighbor neighbor0(&edge, node1, length, max_width);
|
||||
node0->neighbors.push_back(neighbor0);
|
||||
VoronoiGraph::Node::Neighbor neighbor1(edge.twin(), node0, length, max_width);
|
||||
node1->neighbors.push_back(neighbor1);
|
||||
node0->neighbors.emplace_back(&edge, node1, neighbor_size);
|
||||
node1->neighbors.emplace_back(edge.twin(), node0, std::move(neighbor_size));
|
||||
}
|
||||
return skeleton;
|
||||
}
|
||||
@ -485,7 +558,7 @@ double VoronoiGraphUtils::get_neighbor_distance(const VoronoiGraph::Node *from,
|
||||
{
|
||||
const VoronoiGraph::Node::Neighbor *neighbor = get_neighbor(from, to);
|
||||
assert(neighbor != nullptr);
|
||||
return neighbor->edge_length;
|
||||
return neighbor->length();
|
||||
}
|
||||
|
||||
VoronoiGraph::Path VoronoiGraphUtils::find_longest_path_on_circle(
|
||||
@ -608,7 +681,7 @@ VoronoiGraph::Path VoronoiGraphUtils::find_longest_path_on_circles(
|
||||
continue; // out of circles
|
||||
if (done.find(neighbor.node) != done.end()) continue;
|
||||
VoronoiGraph::Path neighbor_path = path; // make copy
|
||||
neighbor_path.append(neighbor.node, neighbor.edge_length);
|
||||
neighbor_path.append(neighbor.node, neighbor.length());
|
||||
search_queue.push(neighbor_path);
|
||||
|
||||
auto branches_item = ex_path.side_branches.find(neighbor.node);
|
||||
@ -655,7 +728,7 @@ std::optional<VoronoiGraph::Circle> VoronoiGraphUtils::create_circle(
|
||||
VoronoiGraph::Nodes circle_path(path_item, passed_nodes.end());
|
||||
// !!! Real circle lenght is calculated on detection of end circle
|
||||
// now circle_length contain also lenght of path before circle
|
||||
double circle_length = path.length + neighbor.edge_length;
|
||||
double circle_length = path.length + neighbor.length();
|
||||
// solve of branch length will be at begin of cirlce
|
||||
return VoronoiGraph::Circle(std::move(circle_path), circle_length);
|
||||
};
|
||||
@ -933,12 +1006,12 @@ VoronoiGraph::Position VoronoiGraphUtils::align(
|
||||
};
|
||||
std::queue<NodeDistance> process;
|
||||
const VoronoiGraph::Node::Neighbor* neighbor = position.neighbor;
|
||||
double from_distance = neighbor->edge_length * position.ratio;
|
||||
double from_distance = neighbor->length() * position.ratio;
|
||||
if (from_distance < max_distance) {
|
||||
const VoronoiGraph::Node *from_node = VoronoiGraphUtils::get_twin_node(neighbor);
|
||||
process.emplace(from_node, from_distance);
|
||||
}
|
||||
double to_distance = neighbor->edge_length * (1 - position.ratio);
|
||||
double to_distance = neighbor->length() * (1 - position.ratio);
|
||||
if (to_distance < max_distance) {
|
||||
const VoronoiGraph::Node *to_node = neighbor->node;
|
||||
process.emplace(to_node, to_distance);
|
||||
@ -966,7 +1039,7 @@ VoronoiGraph::Position VoronoiGraphUtils::align(
|
||||
closest_distance = distance;
|
||||
closest = VoronoiGraph::Position(&neighbor, ratio);
|
||||
}
|
||||
double from_start = nd.distance + neighbor.edge_length;
|
||||
double from_start = nd.distance + neighbor.length();
|
||||
if (from_start < max_distance)
|
||||
process.emplace(neighbor.node, from_start);
|
||||
}
|
||||
@ -1013,9 +1086,9 @@ const VoronoiGraph::Node *VoronoiGraphUtils::getFirstContourNode(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
double VoronoiGraphUtils::get_max_width(const VoronoiGraph::Nodes &path)
|
||||
coord_t VoronoiGraphUtils::get_max_width(const VoronoiGraph::Nodes &path)
|
||||
{
|
||||
double max = 0.;
|
||||
coord_t max = 0;
|
||||
const VoronoiGraph::Node *prev_node = nullptr;
|
||||
for (const VoronoiGraph::Node *node : path) {
|
||||
if (prev_node == nullptr) {
|
||||
@ -1023,16 +1096,16 @@ double VoronoiGraphUtils::get_max_width(const VoronoiGraph::Nodes &path)
|
||||
continue;
|
||||
}
|
||||
const VoronoiGraph::Node::Neighbor *neighbor = get_neighbor(prev_node, node);
|
||||
if (max < neighbor->max_width) max = neighbor->max_width;
|
||||
if (max < neighbor->max_width()) max = neighbor->max_width();
|
||||
prev_node = node;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
double VoronoiGraphUtils::get_max_width(
|
||||
coord_t VoronoiGraphUtils::get_max_width(
|
||||
const VoronoiGraph::ExPath &longest_path)
|
||||
{
|
||||
double max = get_max_width(longest_path.nodes);
|
||||
coord_t max = get_max_width(longest_path.nodes);
|
||||
for (const auto &side_branches_item : longest_path.side_branches) {
|
||||
const VoronoiGraph::Node *prev_node = side_branches_item.first;
|
||||
VoronoiGraph::ExPath::SideBranches side_branches = side_branches_item.second; // !!! copy
|
||||
@ -1040,8 +1113,8 @@ double VoronoiGraphUtils::get_max_width(
|
||||
const VoronoiGraph::Path &side_path = side_branches.top();
|
||||
const VoronoiGraph::Node::Neighbor *first_neighbor =
|
||||
get_neighbor(prev_node, side_path.nodes.front());
|
||||
double max_side_branch = std::max(
|
||||
get_max_width(side_path.nodes), first_neighbor->max_width);
|
||||
coord_t max_side_branch = std::max(
|
||||
get_max_width(side_path.nodes), first_neighbor->max_width());
|
||||
if (max < max_side_branch) max = max_side_branch;
|
||||
side_branches.pop();
|
||||
}
|
||||
@ -1051,7 +1124,7 @@ double VoronoiGraphUtils::get_max_width(
|
||||
const VoronoiGraph::Node::Neighbor *first_neighbor =
|
||||
get_neighbor(circle.nodes.front(), circle.nodes.back());
|
||||
double max_circle = std::max(
|
||||
first_neighbor->max_width, get_max_width(circle.nodes));
|
||||
first_neighbor->max_width(), get_max_width(circle.nodes));
|
||||
if (max < max_circle) max = max_circle;
|
||||
}
|
||||
|
||||
@ -1059,9 +1132,9 @@ double VoronoiGraphUtils::get_max_width(
|
||||
}
|
||||
|
||||
// !!! is slower than go along path
|
||||
double VoronoiGraphUtils::get_max_width(const VoronoiGraph::Node *node)
|
||||
coord_t VoronoiGraphUtils::get_max_width(const VoronoiGraph::Node *node)
|
||||
{
|
||||
double max = 0.;
|
||||
coord_t max = 0;
|
||||
std::set<const VoronoiGraph::Node *> done;
|
||||
std::queue<const VoronoiGraph::Node *> process;
|
||||
process.push(node);
|
||||
@ -1072,7 +1145,7 @@ double VoronoiGraphUtils::get_max_width(const VoronoiGraph::Node *node)
|
||||
for (const VoronoiGraph::Node::Neighbor& neighbor: actual_node->neighbors) {
|
||||
if (done.find(neighbor.node) != done.end()) continue;
|
||||
process.push(neighbor.node);
|
||||
if (max < neighbor.max_width) max = neighbor.max_width;
|
||||
if (max < neighbor.max_width()) max = neighbor.max_width();
|
||||
}
|
||||
done.insert(actual_node);
|
||||
}
|
||||
@ -1081,13 +1154,16 @@ double VoronoiGraphUtils::get_max_width(const VoronoiGraph::Node *node)
|
||||
|
||||
void VoronoiGraphUtils::draw(SVG & svg,
|
||||
const VoronoiGraph &graph,
|
||||
const Lines & lines,
|
||||
coord_t width,
|
||||
bool pointer_caption)
|
||||
bool pointer_caption)
|
||||
{
|
||||
LineUtils::draw(svg, lines, "black", 0., true);
|
||||
|
||||
auto print_address = [&](const Point& p, const char* prefix, void * addr, const char* color){
|
||||
if (pointer_caption) {
|
||||
std::stringstream ss;
|
||||
ss << prefix << std::hex << (int) addr;
|
||||
ss << prefix << std::hex << reinterpret_cast<intptr_t>(addr);
|
||||
std::string s = ss.str();
|
||||
svg.draw_text(p, s.c_str(), color);
|
||||
}
|
||||
@ -1096,7 +1172,7 @@ void VoronoiGraphUtils::draw(SVG & svg,
|
||||
for (const auto &[key, value] : graph.data) {
|
||||
Point p(key->x(), key->y());
|
||||
svg.draw(p, "lightgray", width);
|
||||
print_address(p, "v_",(void*)key, "lightgray");
|
||||
print_address(p, "vertex ptr ",(void*)key, "lightgray");
|
||||
for (const auto &n : value.neighbors) {
|
||||
Point from = to_point(n.edge->vertex0());
|
||||
Point to = to_point(n.edge->vertex1());
|
||||
@ -1104,17 +1180,34 @@ void VoronoiGraphUtils::draw(SVG & svg,
|
||||
Point center = (from + to) / 2;
|
||||
Point p = center + ((is_second) ? Point(0., -2e6) :
|
||||
Point(0., 2e6));
|
||||
print_address(p, "n_", (void *) &n, "gray");
|
||||
print_address(p, "neighbor ptr ", (void *) &n, "gray");
|
||||
if (is_second) continue;
|
||||
svg.draw_text(center + Point(-6e6, 0.), ("w="+std::to_string(n.max_width)).c_str(), "gray");
|
||||
svg.draw(Line(from, to), "gray", width);
|
||||
|
||||
// svg.draw_text(center,
|
||||
// (std::to_string(std::round(n.edge_length/3e5)/100.)).c_str(), "gray");
|
||||
std::string width_str = "width min=" + std::to_string(n.min_width()) +
|
||||
" max=" + std::to_string(n.max_width());
|
||||
svg.draw_text(center + Point(-6e6, 0.), width_str.c_str(), "gray");
|
||||
draw(svg, *n.edge, lines, "gray", width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoronoiGraphUtils::draw(SVG & svg,
|
||||
const VD::edge_type &edge,
|
||||
const Lines & lines,
|
||||
const char * color,
|
||||
coord_t width)
|
||||
{
|
||||
Point from = to_point(edge.vertex0());
|
||||
Point to = to_point(edge.vertex1());
|
||||
if (edge.is_curved()) {
|
||||
Parabola p = get_parabola(edge, lines);
|
||||
ParabolaSegment ps(p, from, to);
|
||||
ParabolaUtils::draw(svg, ps, color, width);
|
||||
return;
|
||||
}
|
||||
svg.draw(Line(from, to), color, width);
|
||||
}
|
||||
|
||||
|
||||
void VoronoiGraphUtils::draw(SVG & svg,
|
||||
const VoronoiGraph::Nodes &path,
|
||||
coord_t width,
|
||||
|
@ -162,6 +162,7 @@ public:
|
||||
/// <returns>Point from source points.</returns>
|
||||
static const Point& retrieve_point(const Points &points, const VD::cell_type &cell);
|
||||
|
||||
private:
|
||||
/// <summary>
|
||||
/// PRIVATE: function to get parabola focus point
|
||||
/// </summary>
|
||||
@ -171,13 +172,14 @@ public:
|
||||
static Point get_parabola_point(const VD::edge_type ¶bola, const Lines &lines);
|
||||
|
||||
/// <summary>
|
||||
/// PRIVATE:
|
||||
/// PRIVATE: function to get parabola diretrix
|
||||
/// </summary>
|
||||
/// <param name="parabola"></param>
|
||||
/// <param name="lines"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="parabola">curved edge</param>
|
||||
/// <param name="lines">source lines</param>
|
||||
/// <returns>Parabola diretrix</returns>
|
||||
static Line get_parabola_line(const VD::edge_type ¶bola, const Lines &lines);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Construct parabola from curved edge
|
||||
/// </summary>
|
||||
@ -204,12 +206,31 @@ public:
|
||||
|
||||
/// <summary>
|
||||
/// Calculate maximal distance to outline and multiply by two(must be similar on both side)
|
||||
/// ! not used
|
||||
/// </summary>
|
||||
/// <param name="edge">Input edge.</param>
|
||||
/// <param name="lines">Source for Voronoi diagram. It contains parabola parameters</param>
|
||||
/// <returns>Maximal island width along edge</returns>
|
||||
static double calculate_max_width(const VD::edge_type &edge, const Lines &lines);
|
||||
|
||||
/// <summary>
|
||||
/// Calculate width limit(min, max) and round value to coord_t
|
||||
/// </summary>
|
||||
/// <param name="edge">Input edge</param>
|
||||
/// <param name="lines">Source for Voronoi diagram. It contains parabola parameters</param>
|
||||
/// <returns>Width range for edge.
|
||||
/// First is minimal width on edge.
|
||||
/// Second is maximal width on edge.</returns>
|
||||
static std::pair<coord_t, coord_t> calculate_width(const VD::edge_type &edge, const Lines &lines);
|
||||
|
||||
private:
|
||||
static std::pair<coord_t, coord_t> calculate_width_for_line(
|
||||
const VD::edge_type &line_edge, const Lines &lines);
|
||||
static std::pair<coord_t, coord_t> calculate_width_for_parabola(
|
||||
const VD::edge_type ¶bola_edge, const Lines &lines);
|
||||
static std::pair<coord_t, coord_t> min_max_width(const VD::edge_type &edge, const Point &point);
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// calculate distances to border of island and length on skeleton
|
||||
/// </summary>
|
||||
@ -405,9 +426,9 @@ public:
|
||||
/// </summary>
|
||||
/// <param name="longest_path">Input point to voronoi graph</param>
|
||||
/// <returns>Maximal widht in graph</returns>
|
||||
static double get_max_width(const VoronoiGraph::ExPath &longest_path);
|
||||
static double get_max_width(const VoronoiGraph::Nodes &path);
|
||||
static double get_max_width(const VoronoiGraph::Node *node);
|
||||
static coord_t get_max_width(const VoronoiGraph::ExPath &longest_path);
|
||||
static coord_t get_max_width(const VoronoiGraph::Nodes &path);
|
||||
static coord_t get_max_width(const VoronoiGraph::Node *node);
|
||||
|
||||
/// <summary>
|
||||
/// Check if neighbor is end of VG
|
||||
@ -417,7 +438,16 @@ public:
|
||||
static bool is_last_neighbor(const VoronoiGraph::Node::Neighbor *neighbor);
|
||||
|
||||
public: // draw function for debug
|
||||
static void draw(SVG &svg, const VoronoiGraph &graph, coord_t width, bool pointer_caption = false);
|
||||
static void draw(SVG & svg,
|
||||
const VoronoiGraph &graph,
|
||||
const Lines & lines,
|
||||
coord_t width,
|
||||
bool pointer_caption = false);
|
||||
static void draw(SVG & svg,
|
||||
const VD::edge_type &edge,
|
||||
const Lines & lines,
|
||||
const char * color,
|
||||
coord_t width);
|
||||
static void draw(SVG & svg,
|
||||
const VoronoiGraph::Nodes &path,
|
||||
coord_t width,
|
||||
|
@ -218,7 +218,23 @@ Slic3r::Polygon create_V_shape(double height, double line_width, double angle =
|
||||
return polygons.front();
|
||||
}
|
||||
|
||||
ExPolygon create_tiny_wide_test(double wide, double tiny)
|
||||
ExPolygon create_tiny_wide_test_1(double wide, double tiny)
|
||||
{
|
||||
double hole_size = wide;
|
||||
double width = 2 * wide + hole_size;
|
||||
double height = wide + hole_size + tiny;
|
||||
auto outline = PolygonUtils::create_rect(width, height);
|
||||
auto hole = PolygonUtils::create_rect(hole_size, hole_size);
|
||||
hole.reverse();
|
||||
int hole_move_y = height/2 - (hole_size/2 + tiny);
|
||||
hole.translate(0, hole_move_y);
|
||||
|
||||
ExPolygon result(outline);
|
||||
result.holes = {hole};
|
||||
return result;
|
||||
}
|
||||
|
||||
ExPolygon create_tiny_wide_test_2(double wide, double tiny)
|
||||
{
|
||||
double hole_size = wide;
|
||||
double width = (3 + 1) * wide + 3 * hole_size;
|
||||
@ -290,7 +306,9 @@ ExPolygons createTestIslands(double size)
|
||||
create_square_with_4holes(5 * size, 5 * size / 2 - size / 3),
|
||||
|
||||
// Tiny and wide part together with holes
|
||||
create_tiny_wide_test(3 * size, 2 / 3. * size),
|
||||
ExPolygon(PolygonUtils::create_isosceles_triangle(5. * size, 40. * size)),
|
||||
create_tiny_wide_test_1(3 * size, 2 / 3. * size),
|
||||
create_tiny_wide_test_2(3 * size, 2 / 3. * size),
|
||||
|
||||
// still problem
|
||||
// three support points
|
||||
|
Loading…
x
Reference in New Issue
Block a user