Fix dividing of patch

This commit is contained in:
Filip Sykala - NTB T15p 2022-07-14 14:32:24 +02:00
parent 962763b05a
commit 4889a1a1b1

View File

@ -455,7 +455,6 @@ void store(const SurfacePatches &patches, const std::string &dir);
void store(const Vec3f &vertex, const Vec3f &normal, const std::string &file, float size = 2.f); void store(const Vec3f &vertex, const Vec3f &normal, const std::string &file, float size = 2.f);
void store(const ProjectionDistances &pds, const VCutAOIs &aois, const CutMeshes &meshes, const std::string &file, float width = 0.2f/* [in mm] */); void store(const ProjectionDistances &pds, const VCutAOIs &aois, const CutMeshes &meshes, const std::string &file, float width = 0.2f/* [in mm] */);
void store(const SurfaceCut &cut, const std::string &file, const std::string &contour_dir); void store(const SurfaceCut &cut, const std::string &file, const std::string &contour_dir);
void store(const std::vector<indexed_triangle_set> &models, const std::string &obj_filename); void store(const std::vector<indexed_triangle_set> &models, const std::string &obj_filename);
void store(const std::vector<CutMesh>&models, const std::string &dir); void store(const std::vector<CutMesh>&models, const std::string &dir);
void store(const Emboss::IProjection &projection, const Point &point_to_project, float projection_ratio, const std::string &obj_filename); void store(const Emboss::IProjection &projection, const Point &point_to_project, float projection_ratio, const std::string &obj_filename);
@ -2452,14 +2451,12 @@ using PatchNumber = CutMesh::Property_map<FI, size_t>;
/// <summary> /// <summary>
/// Separate triangles singned with number n /// Separate triangles singned with number n
/// </summary> /// </summary>
/// <param name="n">Order number of patch to separate</param> /// <param name="fis">Face indices owned by separate patch</param>
/// <param name="patch_number">Number for each triangle</param>
/// <param name="patch">Original patch /// <param name="patch">Original patch
/// NOTE: Can't be const. For indexing vetices need temporary add property map</param> /// NOTE: Can't be const. For indexing vetices need temporary add property map</param>
/// <param name="cvt_from">conversion map</param> /// <param name="cvt_from">conversion map</param>
/// <returns>Just separated patch</returns> /// <returns>Just separated patch</returns>
SurfacePatch separate_patch(size_t n, SurfacePatch separate_patch(const std::vector<FI> &fis,
const PatchNumber &patch_number,
/* const*/ SurfacePatch &patch, /* const*/ SurfacePatch &patch,
const CvtVI2VI &cvt_from); const CvtVI2VI &cvt_from);
@ -2571,14 +2568,11 @@ uint32_t priv::get_shape_point_index(const CutAOI &cut, const CutMesh &model)
return 0; return 0;
} }
priv::SurfacePatch priv::separate_patch(size_t n, priv::SurfacePatch priv::separate_patch(const std::vector<FI>& fis,
const PatchNumber &patch_number,
SurfacePatch &patch, SurfacePatch &patch,
const CvtVI2VI &cvt_from) const CvtVI2VI &cvt_from)
{ {
std::vector<FI> fis; assert(patch.mesh.is_valid());
for (FI fi_cm : patch.mesh.faces())
if (patch_number[fi_cm] == n) fis.push_back(fi_cm);
SurfacePatch patch_new = create_surface_patch(fis, patch.mesh); SurfacePatch patch_new = create_surface_patch(fis, patch.mesh);
patch_new.bb = bounding_box(patch_new.mesh); patch_new.bb = bounding_box(patch_new.mesh);
patch_new.aoi_id = patch.aoi_id; patch_new.aoi_id = patch.aoi_id;
@ -2601,46 +2595,55 @@ void priv::divide_patch(size_t i, SurfacePatches &patches) {
constexpr size_t def_value = std::numeric_limits<size_t>::max(); constexpr size_t def_value = std::numeric_limits<size_t>::max();
CutMesh& cm = patch.mesh; CutMesh& cm = patch.mesh;
assert(!cm.faces().empty());
std::string patch_number_name = "f:patch_number"; std::string patch_number_name = "f:patch_number";
PatchNumber patch_number = cm.add_property_map<FI, size_t>(patch_number_name, def_value).first; CutMesh::Property_map<FI,bool> is_processed = cm.add_property_map<FI, bool>(patch_number_name, false).first;
size_t number = 0; const CvtVI2VI& cvt_from = patch.mesh.property_map<VI, VI>(patch_source_name).first;
std::vector<FI> fis;
fis.reserve(cm.faces().size());
SurfacePatches new_patches;
std::vector<FI> queue; std::vector<FI> queue;
// IMPROVE: create groups around triangles and than connect groups // IMPROVE: create groups around triangles and than connect groups
for (FI fi_cm : cm.faces()) { for (FI fi_cm : cm.faces()) {
if (patch_number[fi_cm] != def_value) continue; if (is_processed[fi_cm]) continue;
assert(queue.empty()); assert(queue.empty());
queue.push_back(fi_cm); queue.push_back(fi_cm);
if (!fis.empty()) {
// Be carefull after push to patches,
// all ref on patch contain non valid values
SurfacePatch patch_n = separate_patch(fis, patches[i], cvt_from);
new_patches.emplace_back(patch_n);
fis.clear();
}
// flood fill from triangle fi_cm to surrounding // flood fill from triangle fi_cm to surrounding
do { do {
FI fi_q = queue.back(); FI fi_q = queue.back();
queue.pop_back(); queue.pop_back();
if (patch_number[fi_q] != def_value) { if (is_processed[fi_q]) continue;
assert(patch_number[fi_q] == number); is_processed[fi_q] = true;
continue; fis.push_back(fi_q);
}
patch_number[fi_q] = number;
HI hi = cm.halfedge(fi_q); HI hi = cm.halfedge(fi_q);
for (FI fi : cm.faces_around_face(hi)) { for (FI fi : cm.faces_around_face(hi)) {
// by documentation The face descriptor may be the null face, and it may be several times the same face descriptor. // by documentation The face descriptor may be the null face, and it may be several times the same face descriptor.
if (!fi.is_valid()) continue; if (!fi.is_valid()) continue;
if (patch_number[fi] == def_value) queue.push_back(fi); if (!is_processed[fi]) queue.push_back(fi);
} }
} while (!queue.empty()); } while (!queue.empty());
++number;
} }
cm.remove_property_map(is_processed);
assert(!fis.empty());
// speed up for only one patch - no dividing (the most common) // speed up for only one patch - no dividing (the most common)
if (number == 1) { if (new_patches.empty()) {
cm.remove_property_map(patch_number);
patch.bb = bounding_box(cm); patch.bb = bounding_box(cm);
return; return;
} else {
patch = separate_patch(fis, patch, cvt_from);
patches.insert(patches.end(), new_patches.begin(), new_patches.end());
} }
const CvtVI2VI& cvt_from = patch.mesh.property_map<VI, VI>(patch_source_name).first;
for (size_t n = 1; n < number; n++)
patches.push_back(separate_patch(n, patch_number, patch, cvt_from));
patch = separate_patch(0, patch_number, patch, cvt_from);
} }
void priv::collect_open_edges(SurfacePatches &patches) { void priv::collect_open_edges(SurfacePatches &patches) {
@ -2693,7 +2696,7 @@ priv::SurfacePatches priv::diff_models(VCutAOIs &cuts,
const CutAOI &cut = model_cuts[cut_index]; const CutAOI &cut = model_cuts[cut_index];
SurfacePatch patch = create_surface_patch(cut.first, cut_model_, &vertex_reduction_map); SurfacePatch patch = create_surface_patch(cut.first, cut_model_, &vertex_reduction_map);
patch.bb = bbs[index]; patch.bb = bbs[index];
patch.aoi_id = index; patch.aoi_id = cut_index;
patch.model_id = model_index; patch.model_id = model_index;
patch.shape_id = get_shape_point_index(cut, cut_model); patch.shape_id = get_shape_point_index(cut, cut_model);
@ -2998,6 +3001,7 @@ void prepare_dir(const std::string &dir){
int reduction_order = 0; int reduction_order = 0;
int filled_order = 0; int filled_order = 0;
int constrained_order = 0; int constrained_order = 0;
int diff_patch_order = 0;
} // namespace priv } // namespace priv
@ -3008,6 +3012,7 @@ void priv::initialize_store(const std::string& dir)
reduction_order = 0; reduction_order = 0;
filled_order = 0; filled_order = 0;
constrained_order = 0; constrained_order = 0;
diff_patch_order = 0;
} }
void priv::store(const Vec3f &vertex, void priv::store(const Vec3f &vertex,