mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-16 08:05:55 +08:00
Optimize speed of recursion function
This commit is contained in:
parent
a9113aa1b9
commit
3d5d6e3cb7
@ -1929,7 +1929,8 @@ struct VoronoiGraph
|
||||
struct Node;
|
||||
using Nodes = std::vector<const Node*>;
|
||||
struct Path;
|
||||
struct Circle;
|
||||
struct ExPath;
|
||||
using Circle = Path;
|
||||
std::map<const VD::vertex_type *, Node> data;
|
||||
};
|
||||
|
||||
@ -1997,7 +1998,7 @@ struct VoronoiGraph::Node::Neighbor
|
||||
// pointer on graph node structure
|
||||
Node *graph_node;
|
||||
|
||||
// full fill constructor
|
||||
public:
|
||||
Neighbor(const VD::edge_type *edge,
|
||||
double edge_length,
|
||||
double longest_distance,
|
||||
@ -2009,36 +2010,53 @@ struct VoronoiGraph::Node::Neighbor
|
||||
{}
|
||||
};
|
||||
|
||||
struct VoronoiGraph::Circle
|
||||
/// <summary>
|
||||
/// Data object represents path over nodes of VoronoiGraph
|
||||
/// store their length of path
|
||||
/// </summary>
|
||||
struct VoronoiGraph::Path
|
||||
{
|
||||
VoronoiGraph::Nodes path;
|
||||
double length;
|
||||
Circle(VoronoiGraph::Nodes path, double length)
|
||||
: path(std::move(path)), length(length)
|
||||
// row of neighbor Nodes
|
||||
VoronoiGraph::Nodes path; // TODO: rename to nodes
|
||||
|
||||
// length of path
|
||||
// when circle contain length from back to front;
|
||||
double length;
|
||||
public:
|
||||
Path() : path(), length(0.) {}
|
||||
Path(VoronoiGraph::Nodes nodes, double length)
|
||||
: path(std::move(nodes)), length(length)
|
||||
{}
|
||||
};
|
||||
|
||||
struct VoronoiGraph::Path
|
||||
/// <summary>
|
||||
/// Data object
|
||||
/// extends path with circles and side branches
|
||||
/// </summary>
|
||||
struct VoronoiGraph::ExPath : public VoronoiGraph::Path
|
||||
{
|
||||
// row of Node created path with length
|
||||
VoronoiGraph::Nodes path;
|
||||
// not main path is stored in secondary paths
|
||||
// key is pointer to source node
|
||||
using SideBranches = std::map<const VoronoiGraph::Node *, std::vector<VoronoiGraph::Path>>;
|
||||
SideBranches side_branches;
|
||||
|
||||
// circles
|
||||
std::vector<VoronoiGraph::Circle> circles;
|
||||
|
||||
//VoronoiGraph::Nodes circles;
|
||||
double length;
|
||||
|
||||
// initial constructor
|
||||
Path(VoronoiGraph::Nodes path, double length)
|
||||
: path(std::move(path)), length(length), side_branches()
|
||||
{}
|
||||
public:
|
||||
ExPath() = default;
|
||||
/// <summary>
|
||||
/// Append new node to path
|
||||
/// </summary>
|
||||
/// <param name="neighbor">node to be append</param>
|
||||
/// <param name="neighbor_distance">distance of new neighbor</param>
|
||||
ExPath(const VoronoiGraph::Node *neighbor_node,
|
||||
double neighbor_distance)
|
||||
{
|
||||
this->path.push_back(neighbor_node);
|
||||
this->length += neighbor_distance;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// calculate distances to border of island and length on skeleton
|
||||
/// </summary>
|
||||
@ -2154,19 +2172,19 @@ double get_neighbor_distance(const VoronoiGraph::Node *from,
|
||||
/// <returns>Longest nodes path and its length</returns>
|
||||
std::pair<VoronoiGraph::Nodes, double> find_longest_path_on_circle(
|
||||
VoronoiGraph::Circle & circle,
|
||||
const VoronoiGraph::Path::SideBranches &side_branches,
|
||||
const VoronoiGraph::ExPath::SideBranches &side_branches,
|
||||
const VoronoiGraph::Path & start_path)
|
||||
{
|
||||
// !! this FIX circle lenght because at detection of circle it will cost time
|
||||
// !! this FIX circle lenght because at detection of circle it will cost time to calculate it
|
||||
circle.length -= start_path.length;
|
||||
|
||||
double half_circle_length = circle.length / 2.;
|
||||
double distance_on_circle = 0;
|
||||
|
||||
double max_length = 0;
|
||||
bool is_longest_revers_direction = false;
|
||||
const VoronoiGraph::Node *longest_circle_node = nullptr;
|
||||
const VoronoiGraph::Path *longest_circle_branch = nullptr;
|
||||
bool is_longest_revers_direction = false;
|
||||
const VoronoiGraph::Node *longest_circle_node = nullptr;
|
||||
const VoronoiGraph::Path *longest_circle_branch = nullptr;
|
||||
double longest_branch_length = 0;
|
||||
|
||||
bool is_short_revers_direction = false;
|
||||
// find longest side branch
|
||||
@ -2179,19 +2197,19 @@ std::pair<VoronoiGraph::Nodes, double> find_longest_path_on_circle(
|
||||
auto side_branches_item = side_branches.find(circle_node);
|
||||
if (side_branches_item != side_branches.end()) {
|
||||
// side_branches should be sorted by length
|
||||
const auto &longest_side_branch = side_branches_item->second.front();
|
||||
if (distance_on_circle > half_circle_length)
|
||||
is_short_revers_direction = true;
|
||||
double node_max_length = start_path.length +
|
||||
longest_side_branch.length +
|
||||
((is_short_revers_direction) ?
|
||||
(circle.length - distance_on_circle) :
|
||||
distance_on_circle);
|
||||
if (max_length < node_max_length) {
|
||||
max_length = node_max_length;
|
||||
const auto &longest_node_branch = side_branches_item->second.front();
|
||||
double circle_branch_length = longest_node_branch.length +
|
||||
((is_short_revers_direction) ?
|
||||
(circle.length -
|
||||
distance_on_circle) :
|
||||
distance_on_circle);
|
||||
if (longest_branch_length < circle_branch_length) {
|
||||
longest_branch_length = circle_branch_length;
|
||||
is_longest_revers_direction = is_short_revers_direction;
|
||||
longest_circle_node = circle_node;
|
||||
longest_circle_branch = &longest_side_branch;
|
||||
longest_circle_branch = &longest_node_branch;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2215,17 +2233,11 @@ std::pair<VoronoiGraph::Nodes, double> find_longest_path_on_circle(
|
||||
circle.path.begin() + 1,
|
||||
circle_iterator+1);
|
||||
}
|
||||
// path befor circle
|
||||
VoronoiGraph::Nodes path = start_path.path;
|
||||
// append part of circle
|
||||
path.insert(path.end(),
|
||||
circle_path.begin(),
|
||||
circle_path.end());
|
||||
// append side branch
|
||||
path.insert(path.end(),
|
||||
// append longest side branch
|
||||
circle_path.insert(circle_path.end(),
|
||||
longest_circle_branch->path.begin(),
|
||||
longest_circle_branch->path.end());
|
||||
return {path ,max_length};
|
||||
return {circle_path, longest_branch_length};
|
||||
}
|
||||
|
||||
|
||||
@ -2233,32 +2245,20 @@ void sort_path_by_length(std::vector<VoronoiGraph::Path> &paths)
|
||||
{
|
||||
if (paths.size() <= 1) return;
|
||||
std::sort(paths.begin(), paths.end(),
|
||||
[](const VoronoiGraph::Path &p1, const VoronoiGraph::Path &p2) {
|
||||
return p1.length > p2.length;
|
||||
[](const VoronoiGraph::Path &path1, const VoronoiGraph::Path &path2) {
|
||||
return path1.length > path2.length;
|
||||
});
|
||||
}
|
||||
|
||||
void create_longest_path_from_point(VoronoiGraph::Path &start_path);
|
||||
void create_longest_path_from_neighbor(
|
||||
VoronoiGraph::Path & next_path,
|
||||
const VoronoiGraph::Node::Neighbor &neighbor)
|
||||
{
|
||||
next_path.length += neighbor.edge_length;
|
||||
const VoronoiGraph::Node *next_node = neighbor.graph_node;
|
||||
next_path.path.push_back(next_node);
|
||||
// stop when it is leaf
|
||||
if (next_node->neighbors.size() == 1) return;
|
||||
return create_longest_path_from_point(next_path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// function for detection circle in passed path
|
||||
/// </summary>
|
||||
/// <param name="path">IN/OUT: If exist append circle to path</param>
|
||||
/// <param name="neighbor">neighbor possible created circle</param>
|
||||
/// <returns>TRUE when circle was created otherwise FALSE</returns>
|
||||
bool create_circle(VoronoiGraph::Path & path,
|
||||
const VoronoiGraph::Node::Neighbor &neighbor)
|
||||
std::optional<VoronoiGraph::Circle> create_circle(
|
||||
const VoronoiGraph::Path &path,
|
||||
const VoronoiGraph::Node::Neighbor &neighbor)
|
||||
{
|
||||
VoronoiGraph::Nodes passed_nodes = path.path;
|
||||
// detection of circle
|
||||
@ -2266,17 +2266,14 @@ bool create_circle(VoronoiGraph::Path & path,
|
||||
auto end_find = passed_nodes.end() - 1;
|
||||
const auto &path_item = std::find(passed_nodes.begin(), end_find,
|
||||
neighbor.graph_node);
|
||||
if (path_item != end_find) { // circle detected
|
||||
// separate Circle:
|
||||
VoronoiGraph::Nodes circle_path(path_item, passed_nodes.end());
|
||||
// !!! Real circle lenght is calculated at fix method,
|
||||
// circle_length contain lenght into start node of circle
|
||||
double circle_length = path.length + neighbor.edge_length;
|
||||
// solve of branch length will be at begin of cirlce
|
||||
path.circles.emplace_back(std::move(circle_path), circle_length);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (path_item == end_find) return {}; // circle not detected
|
||||
// separate Circle:
|
||||
VoronoiGraph::Nodes circle_path(path_item, passed_nodes.end());
|
||||
// !!! Real circle lenght is calculated in function find_longest_path_on_circle
|
||||
// now circle_length contain also lenght of path before circle
|
||||
double circle_length = path.length + neighbor.edge_length;
|
||||
// solve of branch length will be at begin of cirlce
|
||||
return VoronoiGraph::Circle(std::move(circle_path), circle_length);
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
@ -2287,43 +2284,59 @@ bool create_circle(VoronoiGraph::Path & path,
|
||||
/// !! need restructuralization by branch from start path
|
||||
/// </summary>
|
||||
/// <param name="start_path">IN/OUT path in Graph</param>
|
||||
void create_longest_path_from_point(VoronoiGraph::Path& start_path)
|
||||
VoronoiGraph::ExPath create_longest_branch_from_node(
|
||||
const VoronoiGraph::Node &node,
|
||||
double distance_to_node = 0.,
|
||||
const VoronoiGraph::Path &prev_path = VoronoiGraph::Path({},0.))
|
||||
{
|
||||
const VoronoiGraph::Nodes &path = start_path.path;
|
||||
size_t path_size = path.size();
|
||||
assert(path_size >= 1);
|
||||
// append actual node
|
||||
VoronoiGraph::Path act_path = prev_path; // make copy
|
||||
act_path.path.push_back(&node);
|
||||
act_path.length += distance_to_node;
|
||||
|
||||
const VoronoiGraph::Nodes &prev_nodes = prev_path.path;
|
||||
const VoronoiGraph::Node *prev_node =
|
||||
(prev_nodes.size() >= 1) ? prev_nodes.back() : nullptr;
|
||||
|
||||
const VoronoiGraph::Node &node = *path.back();
|
||||
const std::vector<VoronoiGraph::Node::Neighbor> &neighbors = node.neighbors;
|
||||
size_t neighbor_count = neighbors.size();
|
||||
const VoronoiGraph::Node *prev_node =
|
||||
(path_size >= 2) ? path[path_size - 2] : nullptr;
|
||||
|
||||
std::vector<VoronoiGraph::Path> paths;
|
||||
paths.reserve(neighbor_count - 1); // one neighbor is prev node
|
||||
std::vector<VoronoiGraph::Path> side_branches;
|
||||
side_branches.reserve(neighbor_count - 1); // one neighbor is prev node
|
||||
|
||||
// when search on cirle store only branches not search for longest Path
|
||||
bool is_node_on_circle = false;
|
||||
|
||||
// skip node on circle when circle start at this node
|
||||
// vector --> multiple cirle could start at same node
|
||||
// prev node should be skiped to
|
||||
VoronoiGraph::Nodes skip_nodes({prev_node}); // circle
|
||||
|
||||
VoronoiGraph::ExPath result(&node, distance_to_node);
|
||||
// Depth search for path of all neighbors --> fill paths
|
||||
for (const VoronoiGraph::Node::Neighbor &neighbor : neighbors) {
|
||||
if (std::find(skip_nodes.begin(), skip_nodes.end(),
|
||||
neighbor.graph_node) != skip_nodes.end()) continue;
|
||||
|
||||
// detection of circle
|
||||
if (create_circle(start_path, neighbor)) {
|
||||
auto circle_opt = create_circle(act_path, neighbor);
|
||||
if (circle_opt.has_value()) {
|
||||
result.circles.emplace_back(std::move(circle_opt.value()));
|
||||
is_node_on_circle = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// create copy of path(not circles, not side_branches)
|
||||
VoronoiGraph::Path next_path(start_path.path, start_path.length);
|
||||
create_longest_path_from_neighbor(next_path, neighbor);
|
||||
const VoronoiGraph::Node &next_node = *neighbor.graph_node;
|
||||
// is next node leaf ?
|
||||
if (next_node.neighbors.size() == 1) {
|
||||
VoronoiGraph::Path side_branch({&next_node}, neighbor.edge_length);
|
||||
side_branches.emplace_back(std::move(side_branch));
|
||||
continue;
|
||||
}
|
||||
|
||||
VoronoiGraph::ExPath next_path =
|
||||
create_longest_branch_from_node(next_node, neighbor.edge_length, act_path);
|
||||
|
||||
// over all new circles -> check if this node is on circle
|
||||
bool is_circle_neighbor = false;
|
||||
for (VoronoiGraph::Circle &circle : next_path.circles) {
|
||||
@ -2333,7 +2346,7 @@ void create_longest_path_from_point(VoronoiGraph::Path& start_path)
|
||||
if (circle_item == circle.path.begin()) {
|
||||
// find longest path over circle and store it into next_path
|
||||
std::tie(next_path.path, next_path.length) =
|
||||
find_longest_path_on_circle(circle, next_path.side_branches, start_path);
|
||||
find_longest_path_on_circle(circle, next_path.side_branches, act_path);
|
||||
// skip twice checking of circle
|
||||
skip_nodes.push_back(circle.path.back());
|
||||
} else {
|
||||
@ -2343,52 +2356,47 @@ void create_longest_path_from_point(VoronoiGraph::Path& start_path)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: move insted of copy
|
||||
// copy side branches
|
||||
start_path.side_branches.insert(
|
||||
next_path.side_branches.begin(),
|
||||
next_path.side_branches.end());
|
||||
if (!next_path.side_branches.empty())
|
||||
result.side_branches.insert(
|
||||
next_path.side_branches.begin(),
|
||||
next_path.side_branches.end());
|
||||
|
||||
// TODO: move insted of copy
|
||||
// copy circles
|
||||
start_path.circles.insert(
|
||||
start_path.circles.end(),
|
||||
next_path.circles.begin(),
|
||||
next_path.circles.end());
|
||||
if (!next_path.circles.empty())
|
||||
result.circles.insert(
|
||||
result.circles.end(),
|
||||
next_path.circles.begin(),
|
||||
next_path.circles.end());
|
||||
|
||||
if (!is_circle_neighbor)
|
||||
paths.push_back(next_path);
|
||||
side_branches.emplace_back(std::move(next_path));
|
||||
|
||||
}
|
||||
// nothing to store
|
||||
// simple node on circle --> only input and output neighbor
|
||||
if (paths.empty()) return;
|
||||
if (side_branches.empty()) return result;
|
||||
|
||||
// from longest path
|
||||
sort_path_by_length(paths);
|
||||
|
||||
// cut off start_path from branch
|
||||
auto prepare_branches = [](std::vector<VoronoiGraph::Path> &paths,
|
||||
const VoronoiGraph::Path & start_path) {
|
||||
for (VoronoiGraph::Path &path : paths) {
|
||||
path.length -= start_path.length;
|
||||
path.path.erase(path.path.begin(),
|
||||
path.path.begin() + start_path.path.size());
|
||||
}
|
||||
};
|
||||
sort_path_by_length(side_branches);
|
||||
|
||||
if (is_node_on_circle) {
|
||||
// not search for longest path, it will eval on end of circle
|
||||
prepare_branches(paths, start_path);
|
||||
start_path.side_branches[&node] = paths;
|
||||
return;
|
||||
result.side_branches[&node] = side_branches;
|
||||
return result;
|
||||
}
|
||||
|
||||
VoronoiGraph::Path longest_path(std::move(paths.front()));
|
||||
paths.erase(paths.begin());
|
||||
if (!paths.empty()) {
|
||||
prepare_branches(paths, start_path);
|
||||
start_path.side_branches[&node] = paths;
|
||||
VoronoiGraph::Path longest_path(std::move(side_branches.front()));
|
||||
side_branches.erase(side_branches.begin());
|
||||
if (!side_branches.empty()) {
|
||||
result.side_branches[&node] = side_branches;
|
||||
}
|
||||
start_path.path = std::move(longest_path.path);
|
||||
start_path.length = longest_path.length;
|
||||
longest_path.path.insert(longest_path.path.begin(), &node);
|
||||
result.path = std::move(longest_path.path);
|
||||
result.length += longest_path.length;
|
||||
return result;
|
||||
}
|
||||
// only for debug purpose
|
||||
double get_length(VoronoiGraph::Nodes &nodes) {
|
||||
@ -2409,7 +2417,7 @@ double get_length(VoronoiGraph::Nodes &nodes) {
|
||||
/// When exist longer path swap branches
|
||||
/// </summary>
|
||||
/// <param name="path">IN/OUT path to be fixed after creating longest path from one point</param>
|
||||
void reshape_longest_path(VoronoiGraph::Path& path) {
|
||||
void reshape_longest_path(VoronoiGraph::ExPath& path) {
|
||||
assert(path.path.size() >= 1);
|
||||
|
||||
double actual_length = 0.;
|
||||
@ -2462,12 +2470,12 @@ void reshape_longest_path(VoronoiGraph::Path& path) {
|
||||
/// Restructuralize path by branch created from random point
|
||||
/// </summary>
|
||||
/// <param name="start_path">IN/OUT path in Graph</param>
|
||||
VoronoiGraph::Path create_longest_path(const VoronoiGraph::Node *start_node)
|
||||
VoronoiGraph::ExPath create_longest_path(const VoronoiGraph::Node *start_node)
|
||||
{
|
||||
VoronoiGraph::Path path({start_node}, 0.);
|
||||
create_longest_path_from_point(path);
|
||||
reshape_longest_path(path);
|
||||
return path;
|
||||
VoronoiGraph::ExPath longest_path = create_longest_branch_from_node(*start_node);
|
||||
reshape_longest_path(longest_path);
|
||||
// after reshape it shoud be longest path for whole Voronoi Graph
|
||||
return longest_path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -2557,7 +2565,7 @@ Point get_center_of_path(const VoronoiGraph::Nodes& path, double path_length)
|
||||
/// <returns>Vector of sampled points or Empty when distance from edge is bigger than max_distance</returns>
|
||||
std::vector<Point> sample_voronoi_graph(const VoronoiGraph &graph,
|
||||
const SampleConfig &config,
|
||||
VoronoiGraph::Path &longest_path)
|
||||
VoronoiGraph::ExPath &longest_path)
|
||||
{
|
||||
// first vertex on contour:
|
||||
const VoronoiGraph::Node *start_node = nullptr;
|
||||
@ -2599,7 +2607,7 @@ void draw(SVG &svg, const VoronoiGraph &graph, coord_t width)
|
||||
|
||||
Point center = from + to;
|
||||
center *= .5;
|
||||
svg.draw_text(center, (std::to_string(std::round(n.edge_length/3e5)/100.)).c_str(), "gray");
|
||||
//svg.draw_text(center, (std::to_string(std::round(n.edge_length/3e5)/100.)).c_str(), "gray");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2617,13 +2625,13 @@ void draw(SVG &svg, const VoronoiGraph::Nodes& path, coord_t width, const char*
|
||||
Point to(node->vertex->x(), node->vertex->y());
|
||||
svg.draw(Line(from, to), color, width);
|
||||
|
||||
svg.draw_text(from, std::to_string(index - 1).c_str(), color);
|
||||
svg.draw_text(to, std::to_string(index).c_str(), color);
|
||||
//svg.draw_text(from, std::to_string(index - 1).c_str(), color);
|
||||
//svg.draw_text(to, std::to_string(index).c_str(), color);
|
||||
prev_node = node;
|
||||
}
|
||||
}
|
||||
|
||||
void draw(SVG &svg, const VoronoiGraph::Path &path, coord_t width) {
|
||||
void draw(SVG &svg, const VoronoiGraph::ExPath &path, coord_t width) {
|
||||
const char *circlePathColor = "green";
|
||||
const char *sideBranchesColor = "blue";
|
||||
const char *mainPathColor = "red";
|
||||
@ -2642,17 +2650,17 @@ void draw(SVG &svg, const VoronoiGraph::Path &path, coord_t width) {
|
||||
}
|
||||
|
||||
std::vector<Point> sample_in_center(const ExPolygon & island,
|
||||
const SampleConfig &config)
|
||||
const SampleConfig &config, bool visualize = true)
|
||||
{
|
||||
VD vd;
|
||||
Lines lines = to_lines(island);
|
||||
construct_voronoi(lines.begin(), lines.end(), &vd);
|
||||
Slic3r::Voronoi::annotate_inside_outside(vd, lines);
|
||||
VoronoiGraph skeleton = getSkeleton(vd, lines);
|
||||
VoronoiGraph::Path longest_path({},0);
|
||||
VoronoiGraph::ExPath longest_path;
|
||||
std::vector<Point> samples = sample_voronoi_graph(skeleton, config, longest_path);
|
||||
|
||||
{ // visualization
|
||||
if(visualize){ // visualization
|
||||
static int counter = 0;
|
||||
BoundingBox bb;
|
||||
double scale = bb.size().x();
|
||||
@ -2682,10 +2690,30 @@ std::vector<Point> test_island_sampling(const ExPolygon & island,
|
||||
return points;
|
||||
}
|
||||
|
||||
TEST_CASE("Sample speed test on FrogLegs", "[VoronoiSkeleton]") {
|
||||
TriangleMesh mesh = load_model("frog_legs.obj");
|
||||
TriangleMeshSlicer slicer{&mesh};
|
||||
std::vector<float> grid({0.1f});
|
||||
std::vector<ExPolygons> slices;
|
||||
slicer.slice(grid, SlicingMode::Regular, 0.05f, &slices, [] {});
|
||||
ExPolygon frog_leg = slices.front()[1];
|
||||
|
||||
double size = 3e7;
|
||||
SampleConfig cfg;
|
||||
cfg.max_distance = size + 0.1;
|
||||
cfg.sample_size = size / 5;
|
||||
cfg.start_distance = 0.2 * size; // radius of support head
|
||||
cfg.curve_sample = 0.1 * size;
|
||||
cfg.max_length_for_one_support_point = 3 * size;
|
||||
|
||||
for (int i = 0; i < 1; ++i) {
|
||||
auto points = sample_in_center(frog_leg, cfg, false);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Sample small islands", "[VoronoiSkeleton]")
|
||||
{
|
||||
double size = 3e7;
|
||||
int count = 5;
|
||||
ExPolygon triangle(
|
||||
Polygon{{.0, .0},
|
||||
{size, .0},
|
||||
@ -2741,27 +2769,24 @@ TEST_CASE("Sample small islands", "[VoronoiSkeleton]")
|
||||
{4 * size5, size5},
|
||||
{3 * size5, size5}}};
|
||||
|
||||
|
||||
//*
|
||||
TriangleMesh mesh = load_model("frog_legs.obj");
|
||||
TriangleMeshSlicer slicer{&mesh};
|
||||
|
||||
|
||||
std::vector<float> grid({
|
||||
0.1f
|
||||
//static_cast<float>(mesh.bounding_box().center().z())
|
||||
});
|
||||
std::vector<float> grid({ 0.1f });
|
||||
std::vector<ExPolygons> slices;
|
||||
slicer.slice(grid, SlicingMode::Regular, 0.05f, &slices, [] {});
|
||||
ExPolygon frog_leg = slices.front()[1];
|
||||
ExPolygon frog_leg = slices.front()[1]; //*/
|
||||
|
||||
SampleConfig cfg;
|
||||
cfg.max_distance = size + 0.1;
|
||||
cfg.sample_size = size / count;
|
||||
cfg.sample_size = size / 5;
|
||||
cfg.start_distance = 0.2*size; // radius of support head
|
||||
cfg.curve_sample = 0.1 *size;
|
||||
cfg.max_length_for_one_support_point = 3 * size;
|
||||
|
||||
ExPolygons islands = {
|
||||
triangle
|
||||
ExPolygons islands = { frog_leg,
|
||||
triangle
|
||||
, square
|
||||
, sharp_triangle
|
||||
, rect
|
||||
|
Loading…
x
Reference in New Issue
Block a user