mirror of
https://git.mirrors.martin98.com/https://github.com/prusa3d/PrusaSlicer.git
synced 2025-08-16 12:15:53 +08:00
experimental algoritmus for support placing
This commit is contained in:
parent
df554623bd
commit
5d44ebd040
@ -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 ¤t_index : triangle_indexes_by_z) {
|
||||
Triangle ¤t = 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user