experimental algoritmus for support placing

This commit is contained in:
PavelMikus 2022-02-21 17:45:09 +01:00
parent df554623bd
commit 5d44ebd040

View File

@ -6,72 +6,146 @@
#include "slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp"
#include "libslic3r/TriangleSelector.hpp"
#include <boost/nowide/cstdio.hpp>
#include <boost/log/trivial.hpp>
namespace Slic3r::GUI {
//TODO close in seprate namespace
static constexpr size_t empty { size_t(-1) };
struct Triangle {
stl_triangle_vertex_indices indices;
Vec3f normal;
size_t index_in_its;
Vec3i neighbours;
float min_z;
Vec3f z_coords_sorted_asc;
//members updated during algorithm
size_t area { 0 };
float strength { 0.0 };
bool supports = false;
bool visited = false;
};
inline float face_area(const stl_vertex vertex[3]) {
return (vertex[1] - vertex[0]).cross(vertex[2] - vertex[1]).norm() / 2;
}
inline float its_face_area(const indexed_triangle_set &its, const stl_triangle_vertex_indices face)
{
const stl_vertex vertices[3] { its.vertices[face[0]], its.vertices[face[1]], its.vertices[face[2]] };
return face_area(vertices);
}
inline float its_face_area(const indexed_triangle_set &its, const int face_idx)
{
return its_face_area(its, its.indices[face_idx]);
}
struct SupportPlacerMesh {
const float supportable_area_budget = 200000.0;
indexed_triangle_set mesh;
std::vector<Triangle> triangles;
std::vector<size_t> triangle_indexes_by_z;
explicit SupportPlacerMesh(indexed_triangle_set &&mesh) :
mesh(mesh) {
explicit SupportPlacerMesh(indexed_triangle_set &&t_mesh) :
mesh(t_mesh) {
auto neighbours = its_face_neighbors_par(mesh);
auto min_z_point = [](const size_t &t_index) {
const auto &t = triangles[t_index];
return std::min(mesh.vertices[t.indices.z()].z(),
std::min(mesh.vertices[t.indices.x()].z(), mesh.vertices[t.indices.y()].z()));
auto z_coords_sorted = [&](const size_t &face_index) {
const auto &face = mesh.indices[face_index];
Vec3f z_coords = Vec3f { mesh.vertices[face.x()].z(), mesh.vertices[face.y()].z(),
mesh.vertices[face.z()].z() };
;
std::sort(z_coords.data(), z_coords.data() + 3);
return z_coords;
};
for (size_t face_index = 0; face_index < mesh.indices; ++face_index) {
for (size_t face_index = 0; face_index < mesh.indices.size(); ++face_index) {
Vec3f normal = its_face_normal(mesh, face_index);
triangles.push_back(Triangle { mesh.indices[face_index], normal, face_index, neighbours[face_index],
min_z_point(face_index) });
z_coords_sorted(face_index) });
triangle_indexes_by_z.push_back(face_index);
}
std::sort(triangle_indexes_by_z.begin(), triangle_indexes_by_z.end(),
[&](const size_t &left, const size_t &right) {
return triangles[left].min_z < triangles[right].min_z;
for (int i = 0; i < triangles[left].z_coords_sorted_asc.size(); ++i) {
if (triangles[left].z_coords_sorted_asc.data()[i]
< triangles[right].z_coords_sorted_asc.data()[i]) {
return true;
}
if (triangles[left].z_coords_sorted_asc.data()[i]
> triangles[right].z_coords_sorted_asc.data()[i]) {
return false;
}
}
return false;
});
}
void assign_areas() {
size_t next_to_process = 0;
while (next_to_process < triangles.size()) {
if (triangles[next_to_process].area > 0){
//already done, skip
void find_support_areas() {
for (const size_t &current_index : triangle_indexes_by_z) {
Triangle &current = triangles[current_index];
float dot_product = current.normal.dot(Vec3f::UnitZ());
std::cout << "EXP: dot_product : " << dot_product << std::endl;
if (dot_product >= 0) {
current.strength = supportable_area_budget;
current.visited = true;
current.supports = false;
} else {
for (const auto &neighbour_index : current.neighbours) {
const Triangle &neighbour = triangles[neighbour_index];
if (!neighbour.visited) {
//not visited yet, ignore
continue;
} else {
std::cout << "EXP: neighbour visited " << std::endl;
float support_cost = -dot_product * dot_product * dot_product
* its_face_area(mesh, current.index_in_its);
std::cout << "EXP: support_cost: " << support_cost << std::endl;
std::cout << "EXP: neighbour strength " << neighbour.strength << std::endl;
if (neighbour.strength < support_cost) {
continue;
} else {
current.strength = neighbour.strength - support_cost;
current.visited = true;
current.supports = false;
break;
}
}
}
if (!current.visited) {
std::cout << "EXP: suports enforced " << std::endl;
current.supports = true;
current.visited = true;
current.strength = its_face_area(mesh, current.index_in_its);
}
}
}
}
}
;
};
void do_experimental_support_placement(indexed_triangle_set mesh,
const TriangleSelectorGUI *selector) {
inline void do_experimental_support_placement(indexed_triangle_set mesh,
TriangleSelectorGUI *selector) {
SupportPlacerMesh support_placer { std::move(mesh) };
support_placer.assign_areas();
support_placer.find_support_areas();
for (const Triangle &t : support_placer.triangles) {
if (t.supports) {
selector->set_facet(t.index_in_its, EnforcerBlockerType::ENFORCER);
selector->request_update_render_data();
}
}
}
}