mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-14 10:15:55 +08:00
Position of Support Point is connected with voronoi graph
This commit is contained in:
parent
dd61478fd6
commit
51dfdd8f38
@ -12,8 +12,20 @@
|
|||||||
|
|
||||||
using namespace Slic3r::sla;
|
using namespace Slic3r::sla;
|
||||||
|
|
||||||
Slic3r::Point SampleIslandUtils::get_point_on_path(
|
SupportIslandPoint SampleIslandUtils::create_point(
|
||||||
const VoronoiGraph::Nodes &path, double distance)
|
const VoronoiGraph::Node::Neighbor *neighbor,
|
||||||
|
double ratio,
|
||||||
|
SupportIslandPoint::Type type)
|
||||||
|
{
|
||||||
|
VoronoiGraph::Position position(neighbor, ratio);
|
||||||
|
Slic3r::Point p = VoronoiGraphUtils::get_edge_point(neighbor->edge, ratio);
|
||||||
|
return SupportIslandPoint(p, type, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
SupportIslandPoint SampleIslandUtils::create_point_on_path(
|
||||||
|
const VoronoiGraph::Nodes &path,
|
||||||
|
double distance,
|
||||||
|
SupportIslandPoint::Type type)
|
||||||
{
|
{
|
||||||
const VoronoiGraph::Node *prev_node = nullptr;
|
const VoronoiGraph::Node *prev_node = nullptr;
|
||||||
double actual_distance = 0.;
|
double actual_distance = 0.;
|
||||||
@ -30,7 +42,7 @@ Slic3r::Point SampleIslandUtils::get_point_on_path(
|
|||||||
double previous_distance = actual_distance - distance;
|
double previous_distance = actual_distance - distance;
|
||||||
double over_ratio = previous_distance / neighbor->edge_length;
|
double over_ratio = previous_distance / neighbor->edge_length;
|
||||||
double ratio = 1. - over_ratio;
|
double ratio = 1. - over_ratio;
|
||||||
return VoronoiGraphUtils::get_edge_point(neighbor->edge, ratio);
|
return create_point(neighbor, ratio, type);
|
||||||
}
|
}
|
||||||
prev_node = node;
|
prev_node = node;
|
||||||
}
|
}
|
||||||
@ -40,14 +52,20 @@ Slic3r::Point SampleIslandUtils::get_point_on_path(
|
|||||||
return Point(0, 0);
|
return Point(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SupportIslandPoint SampleIslandUtils::create_middle_path_point(
|
||||||
|
const VoronoiGraph::Path &path, SupportIslandPoint::Type type)
|
||||||
|
{
|
||||||
|
return create_point_on_path(path.nodes, path.length / 2, type);
|
||||||
|
}
|
||||||
|
|
||||||
SupportIslandPoints SampleIslandUtils::create_side_points(
|
SupportIslandPoints SampleIslandUtils::create_side_points(
|
||||||
const VoronoiGraph::Nodes &path, double side_distance)
|
const VoronoiGraph::Nodes &path, double side_distance)
|
||||||
{
|
{
|
||||||
VoronoiGraph::Nodes reverse_path = path; // copy
|
VoronoiGraph::Nodes reverse_path = path; // copy
|
||||||
std::reverse(reverse_path.begin(), reverse_path.end());
|
std::reverse(reverse_path.begin(), reverse_path.end());
|
||||||
return {
|
return {
|
||||||
{get_point_on_path(path, side_distance), SupportIslandPoint::Type::two_points},
|
create_point_on_path(path, side_distance, SupportIslandPoint::Type::two_points),
|
||||||
{get_point_on_path(reverse_path, side_distance), SupportIslandPoint::Type::two_points}
|
create_point_on_path(reverse_path, side_distance, SupportIslandPoint::Type::two_points)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +82,7 @@ SupportIslandPoints SampleIslandUtils::sample_side_branch(
|
|||||||
VoronoiGraph::Nodes reverse_path = side_path.nodes;
|
VoronoiGraph::Nodes reverse_path = side_path.nodes;
|
||||||
std::reverse(reverse_path.begin(), reverse_path.end());
|
std::reverse(reverse_path.begin(), reverse_path.end());
|
||||||
reverse_path.push_back(first_node);
|
reverse_path.push_back(first_node);
|
||||||
return {get_point_on_path(reverse_path, cfg.side_distance)};
|
return {create_point_on_path(reverse_path, cfg.side_distance)};
|
||||||
}
|
}
|
||||||
// count of segment between points on main path
|
// count of segment between points on main path
|
||||||
size_t segment_count = static_cast<size_t>(
|
size_t segment_count = static_cast<size_t>(
|
||||||
@ -91,8 +109,9 @@ SupportIslandPoints SampleIslandUtils::sample_side_branch(
|
|||||||
}
|
}
|
||||||
while (distance < neighbor->edge_length) {
|
while (distance < neighbor->edge_length) {
|
||||||
double edge_ratio = distance / neighbor->edge_length;
|
double edge_ratio = distance / neighbor->edge_length;
|
||||||
result.emplace_back(VoronoiGraphUtils::get_edge_point(neighbor->edge, edge_ratio),
|
result.emplace_back(
|
||||||
SupportIslandPoint::Type::center_line);
|
create_point(neighbor, edge_ratio, SupportIslandPoint::Type::center_line)
|
||||||
|
);
|
||||||
distance += sample_distance;
|
distance += sample_distance;
|
||||||
}
|
}
|
||||||
distance -= neighbor->edge_length;
|
distance -= neighbor->edge_length;
|
||||||
@ -167,115 +186,284 @@ SupportIslandPoints SampleIslandUtils::sample_center_line(
|
|||||||
start_offset, cfg);
|
start_offset, cfg);
|
||||||
|
|
||||||
if (path.circles.empty()) return result;
|
if (path.circles.empty()) return result;
|
||||||
SupportIslandPoints result_circles = sample_center_circles(path, cfg);
|
sample_center_circles(path, cfg, result);
|
||||||
result.insert(result.end(), result_circles.begin(), result_circles.end());
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SupportIslandPoints SampleIslandUtils::sample_center_circle(
|
void SampleIslandUtils::sample_center_circle_end(
|
||||||
const std::set<const VoronoiGraph::Node *>& circle_set,
|
const VoronoiGraph::Node::Neighbor &neighbor,
|
||||||
const VoronoiGraph::Nodes& path_nodes,
|
double & neighbor_distance,
|
||||||
const CenterLineConfiguration & cfg
|
const VoronoiGraph::Nodes & done_nodes,
|
||||||
)
|
double & node_distance,
|
||||||
|
const CenterLineConfiguration & cfg,
|
||||||
|
SupportIslandPoints & result)
|
||||||
{
|
{
|
||||||
SupportIslandPoints result;
|
double distance = neighbor_distance + node_distance + neighbor.edge_length;
|
||||||
// DTO store information about distance to nearest support point
|
if (distance < cfg.max_sample_distance) { // no need add support point
|
||||||
// and path from start point
|
if (neighbor_distance > node_distance + neighbor.edge_length)
|
||||||
struct NodeDistance
|
neighbor_distance = node_distance + neighbor.edge_length;
|
||||||
|
if (node_distance > neighbor_distance + neighbor.edge_length)
|
||||||
|
node_distance = neighbor_distance + neighbor.edge_length;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t count_supports = static_cast<size_t>(
|
||||||
|
std::floor(distance / cfg.max_sample_distance));
|
||||||
|
// distance between support points
|
||||||
|
double distance_between = distance / (count_supports + 1);
|
||||||
|
if (distance_between < neighbor_distance) {
|
||||||
|
// point is calculated to be in done path, SP will be on edge point
|
||||||
|
result.emplace_back(create_point(&neighbor, 1., SupportIslandPoint::Type::center_circle_end));
|
||||||
|
neighbor_distance = 0.;
|
||||||
|
count_supports -= 1;
|
||||||
|
if (count_supports == 0) {
|
||||||
|
if (node_distance > neighbor.edge_length)
|
||||||
|
node_distance = neighbor.edge_length;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
distance = node_distance + neighbor.edge_length;
|
||||||
|
distance_between = distance / (count_supports + 1);
|
||||||
|
}
|
||||||
|
VoronoiGraph::Nodes nodes = done_nodes; // copy, could be more neighbor
|
||||||
|
nodes.insert(nodes.begin(), neighbor.node);
|
||||||
|
for (int i = 1; i <= count_supports; ++i) {
|
||||||
|
double distance_from_neighbor = i * (distance_between) - neighbor_distance;
|
||||||
|
result.emplace_back(
|
||||||
|
create_point_on_path(nodes, distance_from_neighbor, SupportIslandPoint::Type::center_circle_end2));
|
||||||
|
double distance_support_to_node = fabs(neighbor.edge_length -
|
||||||
|
distance_from_neighbor);
|
||||||
|
if (node_distance > distance_support_to_node)
|
||||||
|
node_distance = distance_support_to_node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DTO store information about distance to nearest support point
|
||||||
|
// and path from start point
|
||||||
|
struct NodeDistance
|
||||||
|
{
|
||||||
|
VoronoiGraph::Nodes nodes; // from act node to start
|
||||||
|
double distance_from_support_point;
|
||||||
|
NodeDistance(const VoronoiGraph::Node *node,
|
||||||
|
double distance_from_support_point)
|
||||||
|
: nodes({node})
|
||||||
|
, distance_from_support_point(distance_from_support_point)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
using SupportDistanceMap = std::map<const VoronoiGraph::Node*, double>;
|
||||||
|
double get_distance_to_support_point(const VoronoiGraph::Node *node,
|
||||||
|
const SupportDistanceMap & support_distance_map,
|
||||||
|
double maximal_search)
|
||||||
|
{
|
||||||
|
auto distance_item = support_distance_map.find(node);
|
||||||
|
if (distance_item != support_distance_map.end())
|
||||||
|
return distance_item->second;
|
||||||
|
|
||||||
|
// wide search for nearest support point by neighbors
|
||||||
|
struct Item
|
||||||
{
|
{
|
||||||
VoronoiGraph::Nodes nodes; // from act node to start
|
const VoronoiGraph::Node *prev_node;
|
||||||
double distance_from_support_point;
|
const VoronoiGraph::Node *node;
|
||||||
NodeDistance(const VoronoiGraph::Node *node,
|
double act_distance;
|
||||||
double distance_from_support_point)
|
bool exist_support_point;
|
||||||
: nodes({node})
|
Item(const VoronoiGraph::Node *prev_node,
|
||||||
, distance_from_support_point(distance_from_support_point)
|
const VoronoiGraph::Node *node,
|
||||||
|
double act_distance,
|
||||||
|
bool exist_support_point = false)
|
||||||
|
: prev_node(prev_node)
|
||||||
|
, node(node)
|
||||||
|
, act_distance(act_distance)
|
||||||
|
, exist_support_point(exist_support_point)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
struct OrderDistanceFromNearest
|
||||||
|
{
|
||||||
|
bool operator()(const Item &first, const Item &second)
|
||||||
|
{
|
||||||
|
return first.act_distance > second.act_distance;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
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);
|
||||||
|
|
||||||
|
while (!process.empty()) {
|
||||||
|
Item i = process.top();
|
||||||
|
if (i.exist_support_point) return i.act_distance;
|
||||||
|
process.pop();
|
||||||
|
auto distance_item = support_distance_map.find(i.node);
|
||||||
|
if (distance_item != support_distance_map.end()) {
|
||||||
|
double distance = i.act_distance + distance_item->second;
|
||||||
|
if (distance > maximal_search) continue;
|
||||||
|
process.emplace(i.prev_node, i.node, distance, true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (const VoronoiGraph::Node::Neighbor &neighbor :i.node->neighbors) {
|
||||||
|
if (neighbor.node == i.prev_node) continue;
|
||||||
|
double distance = i.act_distance + neighbor.edge_length;
|
||||||
|
if (distance > maximal_search) continue;
|
||||||
|
process.emplace(i.node, neighbor.node, distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maximal_search;
|
||||||
|
}
|
||||||
|
|
||||||
|
SupportDistanceMap create_path_distances(
|
||||||
|
const std::set<const VoronoiGraph::Node *> &circle_set,
|
||||||
|
const std::set<const VoronoiGraph::Node *> &path_set,
|
||||||
|
const SupportDistanceMap & support_distance_map,
|
||||||
|
double maximal_search)
|
||||||
|
{
|
||||||
|
SupportDistanceMap path_distances;
|
||||||
|
for (const VoronoiGraph::Node *node : circle_set) {
|
||||||
|
if (path_set.find(node) == path_set.end()) continue; // lay out of path
|
||||||
|
path_distances[node] = get_distance_to_support_point(
|
||||||
|
node, support_distance_map, maximal_search);
|
||||||
|
}
|
||||||
|
return path_distances;
|
||||||
|
}
|
||||||
|
|
||||||
|
SupportDistanceMap create_support_distance_map(const SupportIslandPoints &support_points)
|
||||||
|
{
|
||||||
|
SupportDistanceMap support_distance_map;
|
||||||
|
for (const SupportIslandPoint &support_point : support_points) {
|
||||||
|
const VoronoiGraph::Position &position = support_point.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;
|
||||||
|
|
||||||
|
auto item = support_distance_map.find(node);
|
||||||
|
if (item == support_distance_map.end()) {
|
||||||
|
support_distance_map[node] = distance;
|
||||||
|
} else if (item->second > distance)
|
||||||
|
item->second = distance;
|
||||||
|
|
||||||
|
auto twin_item = support_distance_map.find(twin_node);
|
||||||
|
if (twin_item == support_distance_map.end()) {
|
||||||
|
support_distance_map[twin_node] = twin_distance;
|
||||||
|
} else if (twin_item->second > twin_distance)
|
||||||
|
twin_item->second = twin_distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
return support_distance_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T, class S, class C>
|
||||||
|
const S &get_container_ref(const std::priority_queue<T, S, C> &q)
|
||||||
|
{
|
||||||
|
struct HackedQueue : private std::priority_queue<T, S, C>
|
||||||
|
{
|
||||||
|
static const S &Container(const std::priority_queue<T, S, C> &q)
|
||||||
|
{
|
||||||
|
return q.*&HackedQueue::c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return HackedQueue::Container(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<const VoronoiGraph::Node *> create_path_set(
|
||||||
|
const VoronoiGraph::ExPath &path)
|
||||||
|
{
|
||||||
|
std::queue<const VoronoiGraph::Node *> side_branch_nodes;
|
||||||
|
std::set<const VoronoiGraph::Node *> path_set;
|
||||||
|
for (const VoronoiGraph::Node *node : path.nodes) {
|
||||||
|
path_set.insert(node);
|
||||||
|
auto side_branch_item = path.side_branches.find(node);
|
||||||
|
if (side_branch_item == path.side_branches.end()) continue;
|
||||||
|
side_branch_nodes.push(node);
|
||||||
|
}
|
||||||
|
while (!side_branch_nodes.empty()) {
|
||||||
|
const VoronoiGraph::Node *node = side_branch_nodes.front();
|
||||||
|
side_branch_nodes.pop();
|
||||||
|
auto side_branch_item = path.side_branches.find(node);
|
||||||
|
const std::vector<VoronoiGraph::Path> &side_branches =
|
||||||
|
get_container_ref(side_branch_item->second);
|
||||||
|
for (const VoronoiGraph::Path& side_branch : side_branches)
|
||||||
|
for (const VoronoiGraph::Node *node : side_branch.nodes) {
|
||||||
|
path_set.insert(node);
|
||||||
|
auto side_branch_item = path.side_branches.find(node);
|
||||||
|
if (side_branch_item == path.side_branches.end()) continue;
|
||||||
|
side_branch_nodes.push(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SampleIslandUtils::sample_center_circles(
|
||||||
|
const VoronoiGraph::ExPath & path,
|
||||||
|
const CenterLineConfiguration &cfg,
|
||||||
|
SupportIslandPoints& result)
|
||||||
|
{
|
||||||
|
// vector of connected circle points
|
||||||
|
// for detection path from circle
|
||||||
|
std::vector<std::set<const VoronoiGraph::Node *>> circles_sets =
|
||||||
|
create_circles_sets(path.circles, path.connected_circle);
|
||||||
|
std::set<const VoronoiGraph::Node *> path_set = create_path_set(path);
|
||||||
|
SupportDistanceMap support_distance_map = create_support_distance_map(result);
|
||||||
|
for (const auto &circle_set : circles_sets) {
|
||||||
|
SupportDistanceMap path_distances = create_path_distances(circle_set, path_set, support_distance_map, cfg.max_sample_distance/2);
|
||||||
|
SupportIslandPoints circle_result = sample_center_circle(circle_set, path_distances, cfg);
|
||||||
|
result.insert(result.end(), circle_result.begin(), circle_result.end());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SupportIslandPoints SampleIslandUtils::sample_center_circle(
|
||||||
|
const std::set<const VoronoiGraph::Node *> &circle_set,
|
||||||
|
std::map<const VoronoiGraph::Node *, double>& path_distances,
|
||||||
|
const CenterLineConfiguration & cfg)
|
||||||
|
{
|
||||||
|
SupportIslandPoints result;
|
||||||
// depth search
|
// depth search
|
||||||
std::stack<NodeDistance> process;
|
std::stack<NodeDistance> process;
|
||||||
|
|
||||||
// TODO: propagate distance from support point
|
|
||||||
// distance from nearest support point
|
|
||||||
double path_distance = cfg.max_sample_distance / 2;
|
|
||||||
// path can't be stored in done because it will skip begining of path
|
|
||||||
std::map<const VoronoiGraph::Node *, double> path_distances;
|
|
||||||
// path_nodes are already sampled
|
// path_nodes are already sampled
|
||||||
for (const VoronoiGraph::Node *node : path_nodes) {
|
for (const auto &path_distanc : path_distances) {
|
||||||
// contain
|
process.push(NodeDistance(path_distanc.first, path_distanc.second));
|
||||||
if (circle_set.find(node) != circle_set.end()) {
|
|
||||||
process.push(NodeDistance(node, path_distance));
|
|
||||||
path_distances[node] = path_distance;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: sample circles out of main path
|
// when node is sampled in all side branches.
|
||||||
if (process.empty()) { // TODO: find side branch
|
|
||||||
}
|
|
||||||
|
|
||||||
// when node is sampled in all side branches.
|
|
||||||
// Value is distance to nearest support point
|
// Value is distance to nearest support point
|
||||||
std::map<const VoronoiGraph::Node *, double> done_distance;
|
std::map<const VoronoiGraph::Node *, double> dones;
|
||||||
while (!process.empty()) {
|
while (!process.empty()) {
|
||||||
NodeDistance nd = process.top(); // copy
|
NodeDistance nd = process.top(); // copy
|
||||||
process.pop();
|
process.pop();
|
||||||
const VoronoiGraph::Node *node = nd.nodes.front();
|
const VoronoiGraph::Node *node = nd.nodes.front();
|
||||||
const VoronoiGraph::Node *prev_node =
|
const VoronoiGraph::Node *prev_node = (nd.nodes.size() > 1) ?
|
||||||
(nd.nodes.size() > 1) ? nd.nodes[1] : nullptr;
|
nd.nodes[1] :
|
||||||
auto done_distance_item = done_distance.find(node);
|
nullptr;
|
||||||
if (done_distance_item != done_distance.end()) {
|
auto done_distance_item = dones.find(node);
|
||||||
|
if (done_distance_item != dones.end()) {
|
||||||
if (done_distance_item->second > nd.distance_from_support_point)
|
if (done_distance_item->second > nd.distance_from_support_point)
|
||||||
done_distance_item->second = nd.distance_from_support_point;
|
done_distance_item->second = nd.distance_from_support_point;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
done_distance[node] = nd.distance_from_support_point;
|
// sign node as done with distance to nearest support
|
||||||
bool is_node_on_path = (path_distances.find(node) != path_distances.end());
|
dones[node] = nd.distance_from_support_point;
|
||||||
double &node_distance = done_distance[node]; // append to done node
|
double &node_distance = dones[node]; // append to done node
|
||||||
|
auto path_distance_item = path_distances.find(node);
|
||||||
|
bool is_node_on_path = (path_distance_item != path_distances.end());
|
||||||
|
if (is_node_on_path && node_distance > path_distance_item->second)
|
||||||
|
node_distance = path_distance_item->second;
|
||||||
for (const auto &neighbor : node->neighbors) {
|
for (const auto &neighbor : node->neighbors) {
|
||||||
if (neighbor.node == prev_node) continue;
|
if (neighbor.node == prev_node) continue;
|
||||||
if (circle_set.find(neighbor.node) == circle_set.end()) continue; // out of circle points
|
if (circle_set.find(neighbor.node) == circle_set.end())
|
||||||
|
continue; // out of circle points
|
||||||
auto path_distance_item = path_distances.find(neighbor.node);
|
auto path_distance_item = path_distances.find(neighbor.node);
|
||||||
bool is_neighbor_on_path = (path_distance_item != path_distances.end());
|
bool is_neighbor_on_path = (path_distance_item !=
|
||||||
if (is_node_on_path && is_neighbor_on_path) continue; // already sampled
|
path_distances.end());
|
||||||
auto done_item = done_distance.find(neighbor.node);
|
if (is_node_on_path && is_neighbor_on_path)
|
||||||
bool is_done = done_item != done_distance.end();
|
continue; // already sampled
|
||||||
if (is_done || is_neighbor_on_path) {
|
|
||||||
double &done_distance = (is_done)? done_item->second : path_distance_item->second;
|
auto neighbor_done_item = dones.find(neighbor.node);
|
||||||
double distance = done_distance +
|
bool is_neighbor_done = neighbor_done_item != dones.end();
|
||||||
nd.distance_from_support_point +
|
if (is_neighbor_done || is_neighbor_on_path) {
|
||||||
neighbor.edge_length;
|
double &neighbor_distance = (is_neighbor_done) ?
|
||||||
if (distance < cfg.max_sample_distance) continue;
|
neighbor_done_item->second :
|
||||||
size_t count_supports = static_cast<size_t>(
|
path_distance_item->second;
|
||||||
std::floor(distance / cfg.max_sample_distance));
|
sample_center_circle_end(neighbor, neighbor_distance,
|
||||||
// distance between support points
|
nd.nodes, node_distance, cfg,
|
||||||
double distance_between = distance / (count_supports + 1);
|
result);
|
||||||
if (distance_between < done_distance) {
|
|
||||||
// point is calculated to be in done path, SP will be on edge point
|
|
||||||
result.emplace_back(
|
|
||||||
VoronoiGraphUtils::get_edge_point(neighbor.edge, 1.),
|
|
||||||
SupportIslandPoint::Type::center_circle_end);
|
|
||||||
if (node_distance > neighbor.edge_length)
|
|
||||||
node_distance = neighbor.edge_length;
|
|
||||||
done_distance = 0.;
|
|
||||||
if (count_supports == 1) continue;
|
|
||||||
count_supports -= 1;
|
|
||||||
distance -= done_distance;
|
|
||||||
distance_between = distance / (count_supports + 1);
|
|
||||||
}
|
|
||||||
VoronoiGraph::Nodes nodes = nd.nodes; // copy, could be more neighbor
|
|
||||||
nodes.insert(nodes.begin(), neighbor.node);
|
|
||||||
for (int i = 1; i <= count_supports; ++i) {
|
|
||||||
double distance_from_neighbor =
|
|
||||||
i * (distance_between) -done_distance;
|
|
||||||
result.emplace_back(
|
|
||||||
get_point_on_path(nodes, distance_from_neighbor),
|
|
||||||
SupportIslandPoint::Type::center_circle_end2);
|
|
||||||
double distance_to_node = neighbor.edge_length -
|
|
||||||
distance_from_neighbor;
|
|
||||||
if (distance_to_node > 0. &&
|
|
||||||
node_distance > distance_to_node)
|
|
||||||
node_distance = distance_to_node;
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,8 +477,8 @@ SupportIslandPoints SampleIslandUtils::sample_center_circle(
|
|||||||
.distance_from_support_point -
|
.distance_from_support_point -
|
||||||
nd.distance_from_support_point;
|
nd.distance_from_support_point;
|
||||||
double ratio = distance_from_node / neighbor.edge_length;
|
double ratio = distance_from_node / neighbor.edge_length;
|
||||||
result.emplace_back(VoronoiGraphUtils::get_edge_point(neighbor.edge, ratio),
|
result.emplace_back(
|
||||||
SupportIslandPoint::Type::center_circle);
|
create_point(&neighbor, ratio, SupportIslandPoint::Type::center_circle));
|
||||||
next_nd.distance_from_support_point -= cfg.max_sample_distance;
|
next_nd.distance_from_support_point -= cfg.max_sample_distance;
|
||||||
}
|
}
|
||||||
process.push(next_nd);
|
process.push(next_nd);
|
||||||
@ -299,33 +487,15 @@ SupportIslandPoints SampleIslandUtils::sample_center_circle(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SupportIslandPoints SampleIslandUtils::sample_center_circles(
|
|
||||||
const VoronoiGraph::ExPath &path, const CenterLineConfiguration &cfg)
|
|
||||||
{
|
|
||||||
// vector of connected circle points
|
|
||||||
// for detection path from circle
|
|
||||||
std::vector<std::set<const VoronoiGraph::Node *>> circles_sets =
|
|
||||||
create_circles_sets(path.circles, path.connected_circle);
|
|
||||||
if (circles_sets.size() == 1)
|
|
||||||
return sample_center_circle(circles_sets.front(), path.nodes, cfg);
|
|
||||||
|
|
||||||
SupportIslandPoints result;
|
|
||||||
for (const auto &circle_set : circles_sets) {
|
|
||||||
SupportIslandPoints circle_result = sample_center_circle(circle_set, path.nodes, cfg);
|
|
||||||
result.insert(result.end(), circle_result.begin(), circle_result.end());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
SupportIslandPoints SampleIslandUtils::sample_expath(
|
SupportIslandPoints SampleIslandUtils::sample_expath(
|
||||||
const VoronoiGraph::ExPath &path, const SampleConfig &config)
|
const VoronoiGraph::ExPath &path, const SampleConfig &config)
|
||||||
{
|
{
|
||||||
// 1) One support point
|
// 1) One support point
|
||||||
if (path.length < config.max_length_for_one_support_point) {
|
if (path.length < config.max_length_for_one_support_point) {
|
||||||
// create only one point in center
|
// create only one point in center
|
||||||
Point p = get_center_of_path(path.nodes, path.length);
|
return {
|
||||||
SupportIslandPoint supportIslandPoint(p, SupportIslandPoint::Type::one_center_point);
|
create_middle_path_point(path, SupportIslandPoint::Type::one_center_point)
|
||||||
return {supportIslandPoint};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
double max_width = VoronoiGraphUtils::get_max_width(path);
|
double max_width = VoronoiGraphUtils::get_max_width(path);
|
||||||
@ -356,8 +526,7 @@ SupportIslandPoints SampleIslandUtils::sample_expath(
|
|||||||
// TODO: divide path to sampled parts
|
// TODO: divide path to sampled parts
|
||||||
|
|
||||||
SupportIslandPoints points;
|
SupportIslandPoints points;
|
||||||
points.push_back(VoronoiGraphUtils::get_offseted_point(
|
points.emplace_back(create_point_on_path(path.nodes, config.minimal_distance_from_outline));
|
||||||
*path.nodes.front(), config.minimal_distance_from_outline));
|
|
||||||
|
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
@ -21,14 +21,28 @@ class SampleIslandUtils
|
|||||||
public:
|
public:
|
||||||
SampleIslandUtils() = delete;
|
SampleIslandUtils() = delete;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create support point on edge defined by neighbor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="neighbor">Source edge</param>
|
||||||
|
/// <param name="ratio">Source distance ratio for position on edge</param>
|
||||||
|
/// <param name="type">Type of point</param>
|
||||||
|
/// <returns>created support island point</returns>
|
||||||
|
static SupportIslandPoint create_point(
|
||||||
|
const VoronoiGraph::Node::Neighbor *neighbor,
|
||||||
|
double ratio,
|
||||||
|
SupportIslandPoint::Type type = SupportIslandPoint::Type::undefined);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Find point lay on path with distance from first point on path
|
/// Find point lay on path with distance from first point on path
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">Neighbor connected Nodes</param>
|
/// <param name="path">Neighbor connected Nodes</param>
|
||||||
/// <param name="distance">Distance to final point</param>
|
/// <param name="distance">Distance to final point</param>
|
||||||
/// <returns>Points with distance to first node</returns>
|
/// <returns>Points with distance to first node</returns>
|
||||||
static Point get_point_on_path(const VoronoiGraph::Nodes &path,
|
static SupportIslandPoint create_point_on_path(
|
||||||
double distance);
|
const VoronoiGraph::Nodes &path,
|
||||||
|
double distance,
|
||||||
|
SupportIslandPoint::Type type = SupportIslandPoint::Type::undefined);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Find point lay in center of path
|
/// Find point lay in center of path
|
||||||
@ -38,11 +52,9 @@ public:
|
|||||||
/// <param name="path">Queue of neighbor nodes.(must be neighbor)</param>
|
/// <param name="path">Queue of neighbor nodes.(must be neighbor)</param>
|
||||||
/// <param name="path_length">length of path</param>
|
/// <param name="path_length">length of path</param>
|
||||||
/// <returns>Point laying on voronoi diagram</returns>
|
/// <returns>Point laying on voronoi diagram</returns>
|
||||||
static Point get_center_of_path(const VoronoiGraph::Nodes &path,
|
static SupportIslandPoint create_middle_path_point(
|
||||||
double path_length)
|
const VoronoiGraph::Path &path,
|
||||||
{
|
SupportIslandPoint::Type type = SupportIslandPoint::Type::undefined);
|
||||||
return get_point_on_path(path, path_length / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create 2 points on both ends of path with side distance from border
|
// create 2 points on both ends of path with side distance from border
|
||||||
static SupportIslandPoints create_side_points(const VoronoiGraph::Nodes &path, double side_distance);
|
static SupportIslandPoints create_side_points(const VoronoiGraph::Nodes &path, double side_distance);
|
||||||
@ -78,11 +90,20 @@ public:
|
|||||||
// create points along path and its side branches(recursively) + colve circles
|
// create points along path and its side branches(recursively) + colve circles
|
||||||
static SupportIslandPoints sample_center_line(const VoronoiGraph::ExPath &path, const CenterLineConfiguration &cfg);
|
static SupportIslandPoints sample_center_line(const VoronoiGraph::ExPath &path, const CenterLineConfiguration &cfg);
|
||||||
// create point along multi circles in path
|
// create point along multi circles in path
|
||||||
static SupportIslandPoints sample_center_circles(const VoronoiGraph::ExPath &path, const CenterLineConfiguration &cfg);
|
static void sample_center_circles(const VoronoiGraph::ExPath & path,
|
||||||
|
const CenterLineConfiguration &cfg,
|
||||||
|
SupportIslandPoints & result);
|
||||||
static SupportIslandPoints sample_center_circle(
|
static SupportIslandPoints sample_center_circle(
|
||||||
const std::set<const VoronoiGraph::Node *> &circle_set,
|
const std::set<const VoronoiGraph::Node *> & circle_set,
|
||||||
const VoronoiGraph::Nodes & path_nodes,
|
std::map<const VoronoiGraph::Node *, double> &path_distances,
|
||||||
const CenterLineConfiguration & cfg);
|
const CenterLineConfiguration & cfg);
|
||||||
|
static void sample_center_circle_end(
|
||||||
|
const VoronoiGraph::Node::Neighbor &neighbor,
|
||||||
|
double & neighbor_distance,
|
||||||
|
const VoronoiGraph::Nodes & done_nodes,
|
||||||
|
double & node_distance,
|
||||||
|
const CenterLineConfiguration & cfg,
|
||||||
|
SupportIslandPoints & result);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Decide how to sample path
|
/// Decide how to sample path
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define slic3r_SLA_SuppotstIslands_SupportIslandPoint_hpp_
|
#define slic3r_SLA_SuppotstIslands_SupportIslandPoint_hpp_
|
||||||
|
|
||||||
#include <libslic3r/Point.hpp>
|
#include <libslic3r/Point.hpp>
|
||||||
|
#include "VoronoiGraph.hpp"
|
||||||
|
|
||||||
namespace Slic3r::sla {
|
namespace Slic3r::sla {
|
||||||
|
|
||||||
@ -21,11 +22,22 @@ struct SupportIslandPoint
|
|||||||
};
|
};
|
||||||
|
|
||||||
Slic3r::Point point; // 2 point in layer coordinate
|
Slic3r::Point point; // 2 point in layer coordinate
|
||||||
|
|
||||||
|
// Define position on voronoi graph
|
||||||
|
// Lose data when voronoi graph does NOT exist
|
||||||
|
VoronoiGraph::Position position;
|
||||||
|
|
||||||
Type type;
|
Type type;
|
||||||
|
|
||||||
SupportIslandPoint(Slic3r::Point point, Type type = Type::undefined)
|
SupportIslandPoint(Slic3r::Point point,
|
||||||
: point(std::move(point)), type(type)
|
Type type = Type::undefined,
|
||||||
{}
|
VoronoiGraph::Position position = {})
|
||||||
|
: point(std::move(point)), type(type), position(position)
|
||||||
|
{
|
||||||
|
if (position.neighbor == nullptr) {
|
||||||
|
int i = 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using SupportIslandPoints = std::vector<SupportIslandPoint>;
|
using SupportIslandPoints = std::vector<SupportIslandPoint>;
|
||||||
|
@ -18,6 +18,7 @@ struct VoronoiGraph
|
|||||||
struct Path;
|
struct Path;
|
||||||
struct ExPath;
|
struct ExPath;
|
||||||
using Circle = Path;
|
using Circle = Path;
|
||||||
|
struct Position;
|
||||||
std::map<const VD::vertex_type *, Node> data;
|
std::map<const VD::vertex_type *, Node> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -48,6 +49,8 @@ struct VoronoiGraph::Node
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Surrond GraphNode data type.
|
/// Surrond GraphNode data type.
|
||||||
/// Extend information about voronoi edge.
|
/// Extend information about voronoi edge.
|
||||||
|
/// TODO IMPROVE: extends neighbors for store more edges
|
||||||
|
/// (cumulate Nodes with 2 neighbors - No cross)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
struct VoronoiGraph::Node::Neighbor
|
struct VoronoiGraph::Node::Neighbor
|
||||||
{
|
{
|
||||||
@ -154,5 +157,29 @@ public:
|
|||||||
ExPath() = default;
|
ExPath() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DTO
|
||||||
|
/// Extend neighbor with ratio to edge
|
||||||
|
/// For point position on VoronoiGraph use VoronoiGraphUtils::get_edge_point
|
||||||
|
/// </summary>
|
||||||
|
struct VoronoiGraph::Position
|
||||||
|
{
|
||||||
|
// neighbor is stored inside of voronoi diagram
|
||||||
|
const VoronoiGraph::Node::Neighbor* neighbor;
|
||||||
|
|
||||||
|
// define position on neighbor edge
|
||||||
|
// Value should be in range from 0. to 1. (shrinked when used)
|
||||||
|
// Value 0 means position of edge->vertex0
|
||||||
|
// Value 0.5 is on half edge way between edge->vertex0 and edge->vertex1
|
||||||
|
// Value 1 means position of edge->vertex1
|
||||||
|
double ratio;
|
||||||
|
|
||||||
|
Position(const VoronoiGraph::Node::Neighbor *neighbor, double ratio)
|
||||||
|
: neighbor(neighbor), ratio(ratio)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Position(): neighbor(nullptr), ratio(0.) {}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace Slic3r::sla
|
} // namespace Slic3r::sla
|
||||||
#endif // slic3r_SLA_SuppotstIslands_VoronoiGraph_hpp_
|
#endif // slic3r_SLA_SuppotstIslands_VoronoiGraph_hpp_
|
||||||
|
@ -201,25 +201,6 @@ VoronoiGraph VoronoiGraphUtils::getSkeleton(const VD &vd, const Lines &lines)
|
|||||||
return skeleton;
|
return skeleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
Slic3r::Point VoronoiGraphUtils::get_offseted_point(
|
|
||||||
const VoronoiGraph::Node &node, double padding)
|
|
||||||
{
|
|
||||||
assert(node.neighbors.size() == 1);
|
|
||||||
const VoronoiGraph::Node::Neighbor &neighbor = node.neighbors.front();
|
|
||||||
const VD::edge_type & edge = *neighbor.edge;
|
|
||||||
const VD::vertex_type & v0 = *edge.vertex0();
|
|
||||||
const VD::vertex_type & v1 = *edge.vertex1();
|
|
||||||
Point dir(v0.x() - v1.x(), v0.y() - v1.y());
|
|
||||||
if (node.vertex == &v0)
|
|
||||||
dir *= -1;
|
|
||||||
else
|
|
||||||
assert(node.vertex == &v1);
|
|
||||||
|
|
||||||
double size = neighbor.edge_length / padding;
|
|
||||||
Point move(dir[0] / size, dir[1] / size);
|
|
||||||
return Point(node.vertex->x() + move[0], node.vertex->y() + move[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
const VoronoiGraph::Node::Neighbor *VoronoiGraphUtils::get_neighbor(
|
const VoronoiGraph::Node::Neighbor *VoronoiGraphUtils::get_neighbor(
|
||||||
const VoronoiGraph::Node *from, const VoronoiGraph::Node *to)
|
const VoronoiGraph::Node *from, const VoronoiGraph::Node *to)
|
||||||
{
|
{
|
||||||
@ -531,6 +512,16 @@ VoronoiGraph::ExPath VoronoiGraphUtils::create_longest_path(
|
|||||||
return longest_path;
|
return longest_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const VoronoiGraph::Node *VoronoiGraphUtils::get_twin_node(const VoronoiGraph::Node::Neighbor *neighbor)
|
||||||
|
{
|
||||||
|
auto twin_edge = neighbor->edge->twin();
|
||||||
|
for (const VoronoiGraph::Node::Neighbor n : neighbor->node->neighbors) {
|
||||||
|
if (n.edge == twin_edge) return n.node;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Slic3r::Point VoronoiGraphUtils::get_edge_point(const VD::edge_type *edge,
|
Slic3r::Point VoronoiGraphUtils::get_edge_point(const VD::edge_type *edge,
|
||||||
double ratio)
|
double ratio)
|
||||||
{
|
{
|
||||||
|
@ -185,6 +185,14 @@ public:
|
|||||||
static VoronoiGraph::ExPath create_longest_path(
|
static VoronoiGraph::ExPath create_longest_path(
|
||||||
const VoronoiGraph::Node *start_node);
|
const VoronoiGraph::Node *start_node);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find source node of neighbor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="neighbor">neighbor</param>
|
||||||
|
/// <returns>start node</returns>
|
||||||
|
static const VoronoiGraph::Node *VoronoiGraphUtils::get_twin_node(
|
||||||
|
const VoronoiGraph::Node::Neighbor *neighbor);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create point on edge defined by neighbor
|
/// Create point on edge defined by neighbor
|
||||||
/// in distance defined by edge length ratio
|
/// in distance defined by edge length ratio
|
||||||
|
@ -162,7 +162,9 @@ Slic3r::Polygon square(double size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Slic3r::Polygon rect(double x, double y){
|
Slic3r::Polygon rect(double x, double y){
|
||||||
return {{.0, y}, {.0, .0}, {x, .0}, {x, y}};
|
double x_2 = x / 2;
|
||||||
|
double y_2 = y / 2;
|
||||||
|
return {{-x_2, y_2}, {-x_2, -y_2}, {x_2, -y_2}, {x_2, y_2}};
|
||||||
}
|
}
|
||||||
|
|
||||||
Slic3r::Polygon circle(double radius, size_t count_line_segments) {
|
Slic3r::Polygon circle(double radius, size_t count_line_segments) {
|
||||||
@ -182,12 +184,14 @@ Slic3r::Polygon create_cross_roads(double size, double width)
|
|||||||
{
|
{
|
||||||
auto r1 = rect( 5.3 * size, width);
|
auto r1 = rect( 5.3 * size, width);
|
||||||
r1.rotate(3.14/4);
|
r1.rotate(3.14/4);
|
||||||
|
r1.translate(2 * size, width / 2);
|
||||||
auto r2 = rect(6.1*size, 3/4.*width);
|
auto r2 = rect(6.1*size, 3/4.*width);
|
||||||
r2.rotate(-3.14 / 5);
|
r2.rotate(-3.14 / 5);
|
||||||
|
r2.translate(3 * size, width / 2);
|
||||||
auto r3 = rect(7.9*size, 4/5.*width);
|
auto r3 = rect(7.9*size, 4/5.*width);
|
||||||
r3.translate(Point(-2*size, size));
|
r3.translate(2*size, width/2);
|
||||||
auto r4 = rect(5 / 6. * width, 5.7 * size);
|
auto r4 = rect(5 / 6. * width, 5.7 * size);
|
||||||
r4.translate(Point(size,0.));
|
r4.translate(-size,3*size);
|
||||||
Polygons rr = union_(Polygons({r1, r2, r3, r4}));
|
Polygons rr = union_(Polygons({r1, r2, r3, r4}));
|
||||||
return rr.front();
|
return rr.front();
|
||||||
}
|
}
|
||||||
@ -234,6 +238,22 @@ ExPolygon create_disc(double radius, double width, size_t count_line_segments)
|
|||||||
return ExPolygon(circle(radius + width_2, count_line_segments), hole);
|
return ExPolygon(circle(radius + width_2, count_line_segments), hole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Slic3r::Polygon create_V_shape(double height, double line_width, double angle = M_PI/4) {
|
||||||
|
double angle_2 = angle / 2;
|
||||||
|
auto left_side = rect(line_width, height);
|
||||||
|
auto right_side = left_side;
|
||||||
|
right_side.rotate(-angle_2);
|
||||||
|
double small_move = cos(angle_2) * line_width / 2;
|
||||||
|
double side_move = sin(angle_2) * height / 2 + small_move;
|
||||||
|
right_side.translate(side_move,0);
|
||||||
|
left_side.rotate(angle_2);
|
||||||
|
left_side.translate(-side_move, 0);
|
||||||
|
auto bottom = rect(4 * small_move, line_width);
|
||||||
|
bottom.translate(0., -cos(angle_2) * height / 2 + line_width/2);
|
||||||
|
Polygons polygons = union_(Polygons({left_side, right_side, bottom}));
|
||||||
|
return polygons.front();
|
||||||
|
}
|
||||||
|
|
||||||
ExPolygons createTestIslands(double size)
|
ExPolygons createTestIslands(double size)
|
||||||
{
|
{
|
||||||
bool useFrogLeg = false;
|
bool useFrogLeg = false;
|
||||||
@ -245,22 +265,6 @@ ExPolygons createTestIslands(double size)
|
|||||||
{3 * size / 7, 2 * size},
|
{3 * size / 7, 2 * size},
|
||||||
{2 * size / 7, size / 6},
|
{2 * size / 7, size / 6},
|
||||||
{size / 7, size}});
|
{size / 7, size}});
|
||||||
|
|
||||||
size_t count_cirlce_lines = 16; // test stack overfrow
|
|
||||||
double r_CCW = size / 2;
|
|
||||||
double r_CW = r_CCW - size / 6;
|
|
||||||
// CCW: couter clock wise, CW: clock wise
|
|
||||||
Points circle_CCW, circle_CW;
|
|
||||||
circle_CCW.reserve(count_cirlce_lines);
|
|
||||||
circle_CW.reserve(count_cirlce_lines);
|
|
||||||
for (size_t i = 0; i < count_cirlce_lines; ++i) {
|
|
||||||
double alpha = (2 * M_PI * i) / count_cirlce_lines;
|
|
||||||
double sina = sin(alpha);
|
|
||||||
double cosa = cos(alpha);
|
|
||||||
circle_CCW.emplace_back(-r_CCW * sina, r_CCW * cosa);
|
|
||||||
circle_CW.emplace_back(r_CW * sina, r_CW * cosa);
|
|
||||||
}
|
|
||||||
ExPolygon double_circle(circle_CCW, circle_CW);
|
|
||||||
ExPolygons result = {
|
ExPolygons result = {
|
||||||
// one support point
|
// one support point
|
||||||
ExPolygon(equilateral_triangle(size)),
|
ExPolygon(equilateral_triangle(size)),
|
||||||
@ -270,13 +274,16 @@ ExPolygons createTestIslands(double size)
|
|||||||
ExPolygon(circle(size/2, 10)),
|
ExPolygon(circle(size/2, 10)),
|
||||||
create_square_with_4holes(size, size / 4),
|
create_square_with_4holes(size, size / 4),
|
||||||
create_disc(size/4, size / 4, 10),
|
create_disc(size/4, size / 4, 10),
|
||||||
|
ExPolygon(create_V_shape(2*size/3, size / 4)),
|
||||||
|
|
||||||
// two support points
|
// two support points
|
||||||
ExPolygon(isosceles_triangle(size / 2, 3 * size)), // small sharp triangle
|
ExPolygon(isosceles_triangle(size / 2, 3 * size)), // small sharp triangle
|
||||||
ExPolygon(rect(size / 2, 3 * size)),
|
ExPolygon(rect(size / 2, 3 * size)),
|
||||||
|
ExPolygon(create_V_shape(1.5*size, size/3)),
|
||||||
|
|
||||||
// tiny line support points
|
// tiny line support points
|
||||||
ExPolygon(rect(size / 2, 10 * size)), // long line
|
ExPolygon(rect(size / 2, 10 * size)), // long line
|
||||||
|
ExPolygon(create_V_shape(size*4, size / 3)),
|
||||||
ExPolygon(create_cross_roads(size, size / 3)),
|
ExPolygon(create_cross_roads(size, size / 3)),
|
||||||
create_disc(3*size, size / 4, 30),
|
create_disc(3*size, size / 4, 30),
|
||||||
create_square_with_4holes(5 * size, 5 * size / 2 - size / 3),
|
create_square_with_4holes(5 * size, 5 * size / 2 - size / 3),
|
||||||
@ -437,6 +444,23 @@ TEST_CASE("Sampling speed test on FrogLegs", "[VoronoiSkeleton]")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Delaunay_triangulation_2.h>
|
||||||
|
void cgal_test(const SupportIslandPoints &points, const ExPolygon &island) {
|
||||||
|
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
|
||||||
|
using Delaunay = CGAL::Delaunay_triangulation_2<Kernel>;
|
||||||
|
std::vector<Kernel::Point_2> k_points;
|
||||||
|
k_points.reserve(points.size());
|
||||||
|
std::transform(points.begin(), points.end(), std::back_inserter(k_points),
|
||||||
|
[](const SupportIslandPoint &p) {
|
||||||
|
return Kernel::Point_2(p.point.x(), p.point.y());
|
||||||
|
});
|
||||||
|
Delaunay dt;
|
||||||
|
dt.insert(k_points.begin(), k_points.end());
|
||||||
|
std::cout << dt.number_of_vertices() << std::endl;
|
||||||
|
}*/
|
||||||
|
|
||||||
TEST_CASE("Small islands should be supported in center", "[SupGen][VoronoiSkeleton]")
|
TEST_CASE("Small islands should be supported in center", "[SupGen][VoronoiSkeleton]")
|
||||||
{
|
{
|
||||||
double size = 3e7;
|
double size = 3e7;
|
||||||
@ -444,6 +468,7 @@ TEST_CASE("Small islands should be supported in center", "[SupGen][VoronoiSkelet
|
|||||||
ExPolygons islands = createTestIslands(size);
|
ExPolygons islands = createTestIslands(size);
|
||||||
for (auto &island : islands) {
|
for (auto &island : islands) {
|
||||||
auto points = test_island_sampling(island, cfg);
|
auto points = test_island_sampling(island, cfg);
|
||||||
|
//cgal_test(points, island);
|
||||||
double angle = 3.14 / 3; // cca 60 degree
|
double angle = 3.14 / 3; // cca 60 degree
|
||||||
|
|
||||||
island.rotate(angle);
|
island.rotate(angle);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user