mirror of
https://git.mirrors.martin98.com/https://github.com/bambulab/BambuStudio.git
synced 2025-08-05 19:56:09 +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.
|
||||
class AutoOrienter {
|
||||
public:
|
||||
int face_count_hull;
|
||||
OrientMesh *orient_mesh = NULL;
|
||||
TriangleMesh* mesh;
|
||||
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 is_apperance; // whether a facet is outer apperance
|
||||
Eigen::MatrixXf z_projected;
|
||||
Eigen::VectorXf z_max, z_max_hull; // max of projected z
|
||||
Eigen::VectorXf z_median; // median of projected z
|
||||
Eigen::VectorXf z_mean; // mean of projected z
|
||||
std::vector<Vec3f> face_normals;
|
||||
std::vector<Vec3f> face_normals_hull;
|
||||
OrientParams params;
|
||||
|
||||
|
||||
@ -111,9 +114,9 @@ public:
|
||||
{
|
||||
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();
|
||||
|
||||
@ -181,17 +184,16 @@ public:
|
||||
{
|
||||
int face_count = mesh->facets_count();
|
||||
auto its = mesh->its;
|
||||
auto face_normals = its_face_normals(its);
|
||||
face_normals = its_face_normals(its);
|
||||
areas = Eigen::VectorXf::Zero(face_count);
|
||||
is_apperance = Eigen::VectorXf::Zero(face_count);
|
||||
normals = Eigen::MatrixXf::Zero(face_count, 3);
|
||||
normals_quantize = Eigen::MatrixXf::Zero(face_count, 3);
|
||||
for (size_t i = 0; i < face_count; i++)
|
||||
{
|
||||
float area = its.facet_area(i);
|
||||
if (params.NEGL_FACE_SIZE > 0 && area < params.NEGL_FACE_SIZE)
|
||||
continue;
|
||||
|
||||
normals.row(i) = quantize_vec3f(face_normals[i]);
|
||||
normals.row(i) = face_normals[i];
|
||||
normals_quantize.row(i) = quantize_vec3f(face_normals[i]);
|
||||
areas(i) = area;
|
||||
is_apperance(i) = (its.get_property(i).type == EnumFaceTypes::eExteriorAppearance);
|
||||
count_apperance += (is_apperance(i)==1);
|
||||
@ -208,17 +210,17 @@ public:
|
||||
|
||||
int face_count = mesh_convex_hull.facets_count();
|
||||
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);
|
||||
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++)
|
||||
{
|
||||
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.
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -248,7 +250,37 @@ public:
|
||||
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()
|
||||
{
|
||||
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
|
||||
/// </summary>
|
||||
/// <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(); )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user