| 17 | const static Eigen::IOFormat CSVFormat(Eigen::StreamPrecision, Eigen::DontAlignCols, ",", "\n"); |
| 18 | |
| 19 | void sample_pc_with_blue_noise( |
| 20 | const int & num_points, |
| 21 | const Eigen::MatrixXd & mesh_v, |
| 22 | const Eigen::MatrixXi & mesh_f, |
| 23 | Eigen::MatrixXd & pc, |
| 24 | Eigen::MatrixXd & normals) |
| 25 | { |
| 26 | if(mesh_v.size() == 0 || mesh_f.size() == 0) { |
| 27 | std::cerr << "Error: Input mesh is empty.\n"; |
| 28 | return; |
| 29 | } |
| 30 | |
| 31 | Eigen::VectorXd A; |
| 32 | igl::doublearea(mesh_v, mesh_f, A); |
| 33 | double radius = sqrt(((A.sum()*0.5/(num_points*0.6162910373))/igl::PI)); |
| 34 | std::cout << "Initial Blue noise radius: " << radius << "\n"; |
| 35 | |
| 36 | Eigen::MatrixXd B; |
| 37 | Eigen::VectorXi I; |
| 38 | int max_attempts = 1; |
| 39 | for(int attempt = 0; attempt < max_attempts; ++attempt) |
| 40 | { |
| 41 | igl::blue_noise(mesh_v, mesh_f, radius, B, I, pc); |
| 42 | std::cout<<"successfully generate a set of blue noise!"<<std::endl; |
| 43 | if(pc.rows() >= num_points * 0.9 && pc.rows() <= num_points * 1.1) |
| 44 | { |
| 45 | break; |
| 46 | } |
| 47 | if(pc.rows() == 0) { |
| 48 | std::cerr << "Error: Blue noise sampling generated an empty point cloud. Attempt: " << attempt + 1 << "\n"; |
| 49 | break; |
| 50 | } |
| 51 | radius *= sqrt(num_points * 1.0 / pc.rows()); |
| 52 | //std::cout << "Adjusted Blue noise radius: " << radius << " (Attempt " << attempt + 1 << ")\n"; |
| 53 | } |
| 54 | |
| 55 | if(pc.rows() == 0) { |
| 56 | std::cerr << "Error: Blue noise sampling failed to generate points.\n"; |
| 57 | return; |
| 58 | } |
| 59 | |
| 60 | if (pc.rows() > num_points) |
| 61 | { |
| 62 | std::cout << "Trimming point cloud from " << pc.rows() << " to " << num_points << " points\n"; |
| 63 | std::vector<int> indices(pc.rows()); |
| 64 | std::iota(indices.begin(), indices.end(), 0); |
| 65 | std::shuffle(indices.begin(), indices.end(), std::default_random_engine{}); |
| 66 | indices.resize(num_points); |
| 67 | Eigen::MatrixXd trimmed_pc(num_points, pc.cols()); |
| 68 | //Eigen::MatrixXd trimmed_normals(num_points, normals.cols()); |
| 69 | std::cout << "pc.rows(): " << pc.rows() << ", pc.cols(): " << pc.cols() << std::endl; |
| 70 | //std::cout << "normals.rows(): " << normals.rows() << ", normals.cols(): " << normals.cols() << std::endl; |
| 71 | for (int i = 0; i < num_points; ++i) |
| 72 | { |
| 73 | //std::cout <<"for trimming" << " i is" << i << std::endl; |
| 74 | trimmed_pc.row(i) = pc.row(indices[i]); |
| 75 | //std::cout<<"1"<<std::endl; |
| 76 | //trimmed_normals.row(i) = normals.row(indices[i]); |