mirror of
https://git.mirrors.martin98.com/https://github.com/SoftFever/OrcaSlicer.git
synced 2025-08-16 12:15:51 +08:00
FIX: Fix the benchy orientation bug
[STUDIO-1717]: 1. Add area filter during finding the orientation vectors. The vector with largest area will be selected. 2. Area_accumulation function return the accurate normals. Change-Id: I917e29a0def4904a82d30cf0a92524bbb0da14c1 (cherry picked from commit a79cf2fa89c7247cab37ebd36974529df79f0990)
This commit is contained in:
parent
8713c5ccc4
commit
ccd333e248
@ -57,16 +57,19 @@ namespace orientation {
|
|||||||
// management and spatial index structures for acceleration.
|
// management and spatial index structures for acceleration.
|
||||||
class AutoOrienter {
|
class AutoOrienter {
|
||||||
public:
|
public:
|
||||||
|
int face_count_hull;
|
||||||
OrientMesh *orient_mesh = NULL;
|
OrientMesh *orient_mesh = NULL;
|
||||||
TriangleMesh* mesh;
|
TriangleMesh* mesh;
|
||||||
TriangleMesh mesh_convex_hull;
|
TriangleMesh mesh_convex_hull;
|
||||||
Eigen::MatrixXf normals, normals_hull;
|
Eigen::MatrixXf normals, normals_quantize, normals_hull, normals_hull_quantize;
|
||||||
Eigen::VectorXf areas, areas_hull;
|
Eigen::VectorXf areas, areas_hull;
|
||||||
Eigen::VectorXf is_apperance; // whether a facet is outer apperance
|
Eigen::VectorXf is_apperance; // whether a facet is outer apperance
|
||||||
Eigen::MatrixXf z_projected;
|
Eigen::MatrixXf z_projected;
|
||||||
Eigen::VectorXf z_max, z_max_hull; // max of projected z
|
Eigen::VectorXf z_max, z_max_hull; // max of projected z
|
||||||
Eigen::VectorXf z_median; // median of projected z
|
Eigen::VectorXf z_median; // median of projected z
|
||||||
Eigen::VectorXf z_mean; // mean of projected z
|
Eigen::VectorXf z_mean; // mean of projected z
|
||||||
|
std::vector<Vec3f> face_normals;
|
||||||
|
std::vector<Vec3f> face_normals_hull;
|
||||||
OrientParams params;
|
OrientParams params;
|
||||||
|
|
||||||
|
|
||||||
@ -111,9 +114,9 @@ public:
|
|||||||
{
|
{
|
||||||
orientations = { { 0,0,-1 } }; // original orientation
|
orientations = { { 0,0,-1 } }; // original orientation
|
||||||
|
|
||||||
area_cumulation(normals, areas, 10);
|
area_cumulation_accurate(face_normals, normals_quantize, areas, 10);
|
||||||
|
|
||||||
area_cumulation(normals_hull, areas_hull, 10);
|
area_cumulation_accurate(face_normals_hull, normals_hull_quantize, areas_hull, 10);
|
||||||
|
|
||||||
add_supplements();
|
add_supplements();
|
||||||
|
|
||||||
@ -181,17 +184,16 @@ public:
|
|||||||
{
|
{
|
||||||
int face_count = mesh->facets_count();
|
int face_count = mesh->facets_count();
|
||||||
auto its = mesh->its;
|
auto its = mesh->its;
|
||||||
auto face_normals = its_face_normals(its);
|
face_normals = its_face_normals(its);
|
||||||
areas = Eigen::VectorXf::Zero(face_count);
|
areas = Eigen::VectorXf::Zero(face_count);
|
||||||
is_apperance = Eigen::VectorXf::Zero(face_count);
|
is_apperance = Eigen::VectorXf::Zero(face_count);
|
||||||
normals = Eigen::MatrixXf::Zero(face_count, 3);
|
normals = Eigen::MatrixXf::Zero(face_count, 3);
|
||||||
|
normals_quantize = Eigen::MatrixXf::Zero(face_count, 3);
|
||||||
for (size_t i = 0; i < face_count; i++)
|
for (size_t i = 0; i < face_count; i++)
|
||||||
{
|
{
|
||||||
float area = its.facet_area(i);
|
float area = its.facet_area(i);
|
||||||
if (params.NEGL_FACE_SIZE > 0 && area < params.NEGL_FACE_SIZE)
|
normals.row(i) = face_normals[i];
|
||||||
continue;
|
normals_quantize.row(i) = quantize_vec3f(face_normals[i]);
|
||||||
|
|
||||||
normals.row(i) = quantize_vec3f(face_normals[i]);
|
|
||||||
areas(i) = area;
|
areas(i) = area;
|
||||||
is_apperance(i) = (its.get_property(i).type == EnumFaceTypes::eExteriorAppearance);
|
is_apperance(i) = (its.get_property(i).type == EnumFaceTypes::eExteriorAppearance);
|
||||||
count_apperance += (is_apperance(i)==1);
|
count_apperance += (is_apperance(i)==1);
|
||||||
@ -208,17 +210,17 @@ public:
|
|||||||
|
|
||||||
int face_count = mesh_convex_hull.facets_count();
|
int face_count = mesh_convex_hull.facets_count();
|
||||||
auto its = mesh_convex_hull.its;
|
auto its = mesh_convex_hull.its;
|
||||||
auto face_normals = its_face_normals(its);
|
face_count_hull = mesh_convex_hull.facets_count();
|
||||||
|
face_normals_hull = its_face_normals(its);
|
||||||
areas_hull = Eigen::VectorXf::Zero(face_count);
|
areas_hull = Eigen::VectorXf::Zero(face_count);
|
||||||
normals_hull = Eigen::MatrixXf::Zero(face_count, 3);
|
normals_hull = Eigen::MatrixXf::Zero(face_count_hull, 3);
|
||||||
|
normals_hull_quantize = Eigen::MatrixXf::Zero(face_count_hull, 3);
|
||||||
for (size_t i = 0; i < face_count; i++)
|
for (size_t i = 0; i < face_count; i++)
|
||||||
{
|
{
|
||||||
float area = its.facet_area(i);
|
float area = its.facet_area(i);
|
||||||
if (params.NEGL_FACE_SIZE > 0 && area < params.NEGL_FACE_SIZE)
|
|
||||||
continue;
|
|
||||||
//normals_hull.row(i) = quantize_vec3f(face_normals[i]);
|
|
||||||
//We cannot use quantized vector here, the accumulated error will result in bad orientations.
|
//We cannot use quantized vector here, the accumulated error will result in bad orientations.
|
||||||
normals_hull.row(i) = face_normals[i];
|
normals_hull.row(i) = face_normals_hull[i];
|
||||||
|
normals_hull_quantize.row(i) = quantize_vec3f(face_normals_hull[i]);
|
||||||
areas_hull(i) = area;
|
areas_hull(i) = area;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,7 +250,37 @@ public:
|
|||||||
BOOST_LOG_TRIVIAL(debug) << align_counts[i].first.transpose() << ", area: " << align_counts[i].second;
|
BOOST_LOG_TRIVIAL(debug) << align_counts[i].first.transpose() << ", area: " << align_counts[i].second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//This function is to make sure to return the accurate normal rather than quantized normal
|
||||||
|
void area_cumulation_accurate( std::vector<Vec3f>& normals_, const Eigen::MatrixXf& quantize_normals_, const Eigen::VectorXf& areas_, int num_directions = 10)
|
||||||
|
{
|
||||||
|
std::unordered_map<stl_normal, std::pair<std::vector<float>, Vec3f>, VecHash> alignments_;
|
||||||
|
Vec3f n1 = { 0, 0, 0 };
|
||||||
|
std::vector<float> current_areas = {0, 0};
|
||||||
|
// init to 0
|
||||||
|
for (size_t i = 0; i < areas_.size(); i++) {
|
||||||
|
alignments_.insert(std::pair(quantize_normals_.row(i), std::pair(current_areas, n1)));
|
||||||
|
}
|
||||||
|
// cumulate areas
|
||||||
|
for (size_t i = 0; i < areas_.size(); i++)
|
||||||
|
{
|
||||||
|
alignments_[quantize_normals_.row(i)].first[1] += areas_(i);
|
||||||
|
if (areas_(i) > alignments_[quantize_normals_.row(i)].first[0]){
|
||||||
|
alignments_[quantize_normals_.row(i)].second = normals_[i];
|
||||||
|
alignments_[quantize_normals_.row(i)].first[0] = areas_(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef std::pair<stl_normal, std::pair<std::vector<float>, Vec3f>> PAIR;
|
||||||
|
std::vector<PAIR> align_counts(alignments_.begin(), alignments_.end());
|
||||||
|
sort(align_counts.begin(), align_counts.end(), [](const PAIR& p1, const PAIR& p2) {return p1.second.first[1] > p2.second.first[1]; });
|
||||||
|
|
||||||
|
num_directions = std::min((size_t)num_directions, align_counts.size());
|
||||||
|
for (size_t i = 0; i < num_directions; i++)
|
||||||
|
{
|
||||||
|
orientations.push_back(align_counts[i].second.second);
|
||||||
|
BOOST_LOG_TRIVIAL(debug) << align_counts[i].second.second.transpose() << ", area: " << align_counts[i].second.first[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
void add_supplements()
|
void add_supplements()
|
||||||
{
|
{
|
||||||
std::vector<Vec3f> vecs = { {0, 0, -1} ,{0.70710678, 0, -0.70710678},{0, 0.70710678, -0.70710678},
|
std::vector<Vec3f> vecs = { {0, 0, -1} ,{0.70710678, 0, -0.70710678},{0, 0.70710678, -0.70710678},
|
||||||
@ -264,7 +296,7 @@ public:
|
|||||||
/// remove duplicate orientations
|
/// remove duplicate orientations
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tol">tolerance. default 0.01 =sin(0.57\degree)</param>
|
/// <param name="tol">tolerance. default 0.01 =sin(0.57\degree)</param>
|
||||||
void remove_duplicates(double tol=0.00000001)
|
void remove_duplicates(double tol=0.0000001)
|
||||||
{
|
{
|
||||||
for (auto it = orientations.begin()+1; it < orientations.end(); )
|
for (auto it = orientations.begin()+1; it < orientations.end(); )
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user