Fix: use property map instead of indexing by VI

This commit is contained in:
Filip Sykala - NTB T15p 2022-07-14 08:08:45 +02:00
parent b9ea049ff4
commit 18c10c044d

View File

@ -2106,12 +2106,13 @@ BoundingBoxf3 bounding_box(const SurfacePatch &ecut);
/// Create patch /// Create patch
/// </summary> /// </summary>
/// <param name="fis">Define patch faces</param> /// <param name="fis">Define patch faces</param>
/// <param name="mesh">Source of fis</param> /// <param name="mesh">Source of fis
/// NOTE: Need temporary add property map for convert vertices</param>
/// <param name="rmap">Options to reduce vertices from fis. /// <param name="rmap">Options to reduce vertices from fis.
/// NOTE: Used for skip vertices made by diagonal edge in rectangle of shape side</param> /// NOTE: Used for skip vertices made by diagonal edge in rectangle of shape side</param>
/// <returns>Patch</returns> /// <returns>Patch</returns>
SurfacePatch create_surface_patch(const std::vector<FI> &fis, SurfacePatch create_surface_patch(const std::vector<FI> &fis,
const CutMesh &mesh, /*const*/ CutMesh &mesh,
const ReductionMap *rmap = nullptr); const ReductionMap *rmap = nullptr);
} // namespace priv } // namespace priv
@ -2291,16 +2292,16 @@ BoundingBoxf3 priv::bounding_box(const SurfacePatch &ecut) {
} }
priv::SurfacePatch priv::create_surface_patch(const std::vector<FI> &fis, priv::SurfacePatch priv::create_surface_patch(const std::vector<FI> &fis,
const CutMesh &mesh, /* const */ CutMesh &mesh,
const ReductionMap *rmap) const ReductionMap *rmap)
{ {
std::vector<bool> is_counted(mesh.vertices().size(), {false}); auto is_counted = mesh.add_property_map<VI, bool>("v:is_counted").first;
uint32_t count_vertices = 0; uint32_t count_vertices = 0;
if (rmap == nullptr) { if (rmap == nullptr) {
for (FI fi : fis) for (FI fi : fis)
for (VI vi : mesh.vertices_around_face(mesh.halfedge(fi))) for (VI vi : mesh.vertices_around_face(mesh.halfedge(fi)))
if (!is_counted[vi.idx()]) { if (!is_counted[vi]) {
is_counted[vi.idx()] = true; is_counted[vi] = true;
++count_vertices; ++count_vertices;
} }
} else { } else {
@ -2308,12 +2309,13 @@ priv::SurfacePatch priv::create_surface_patch(const std::vector<FI> &fis,
for (VI vi : mesh.vertices_around_face(mesh.halfedge(fi))) { for (VI vi : mesh.vertices_around_face(mesh.halfedge(fi))) {
// Will vertex be reduced? // Will vertex be reduced?
if ((*rmap)[vi].is_valid()) continue; if ((*rmap)[vi].is_valid()) continue;
if (!is_counted[vi.idx()]) { if (!is_counted[vi]) {
is_counted[vi.idx()] = true; is_counted[vi] = true;
++count_vertices; ++count_vertices;
} }
} }
} }
mesh.remove_property_map(is_counted);
uint32_t count_faces = fis.size(); uint32_t count_faces = fis.size();
// IMPROVE: Value is greater than neccessary, count edges used twice // IMPROVE: Value is greater than neccessary, count edges used twice
@ -2322,21 +2324,20 @@ priv::SurfacePatch priv::create_surface_patch(const std::vector<FI> &fis,
CutMesh cm; CutMesh cm;
cm.reserve(count_vertices, count_edges, count_faces); cm.reserve(count_vertices, count_edges, count_faces);
// vertex conversion function // vertex conversion function from mesh VI to result VI
constexpr uint32_t def_val = std::numeric_limits<uint32_t>::max(); CvtVI2VI mesh2result = mesh.add_property_map<VI,VI>("v:mesh2result").first;
std::vector<uint32_t> v_cvt(mesh.vertices().size(), {def_val});
if (rmap == nullptr) { if (rmap == nullptr) {
for (FI fi : fis) { for (FI fi : fis) {
std::array<VI, 3> t; std::array<VI, 3> t;
int index = 0; int index = 0;
for (VI vi : mesh.vertices_around_face(mesh.halfedge(fi))) { for (VI vi : mesh.vertices_around_face(mesh.halfedge(fi))) {
uint32_t &cvt = v_cvt[vi.idx()]; VI &vi_cvt = mesh2result[vi];
if (cvt == def_val) { if (!vi_cvt.is_valid()) {
cvt = cm.vertices().size(); vi_cvt = VI(cm.vertices().size());
cm.add_vertex(mesh.point(vi)); cm.add_vertex(mesh.point(vi));
} }
t[index++] = VI(cvt); t[index++] = vi_cvt;
} }
cm.add_face(t[0], t[1], t[2]); cm.add_face(t[0], t[1], t[2]);
} }
@ -2351,14 +2352,12 @@ priv::SurfacePatch priv::create_surface_patch(const std::vector<FI> &fis,
exist_reduction = true; exist_reduction = true;
vi = vi_r; vi = vi_r;
} }
VI &vi_cvt = mesh2result[vi];
assert(vi.idx() < v_cvt.size()); if (!vi_cvt.is_valid()) {
uint32_t &cvt = v_cvt[vi.idx()]; vi_cvt = VI(cm.vertices().size());
if (cvt == def_val) {
cvt = cm.vertices().size();
cm.add_vertex(mesh.point(vi)); cm.add_vertex(mesh.point(vi));
} }
t[index++] = VI(cvt); t[index++] = vi_cvt;
} }
// prevent add reduced triangle // prevent add reduced triangle
@ -2371,24 +2370,22 @@ priv::SurfacePatch priv::create_surface_patch(const std::vector<FI> &fis,
cm.add_face(t[0], t[1], t[2]); cm.add_face(t[0], t[1], t[2]);
} }
} }
assert(count_vertices == cm.vertices().size()); assert(count_vertices == cm.vertices().size());
assert((rmap == nullptr && count_faces == cm.faces().size()) || assert((rmap == nullptr && count_faces == cm.faces().size()) ||
(rmap != nullptr && count_faces >= cm.faces().size())); (rmap != nullptr && count_faces >= cm.faces().size()));
assert(count_edges >= cm.edges().size()); assert(count_edges >= cm.edges().size());
// convert VI from this patch to source VI, when exist // convert VI from this patch to source VI, when exist
CvtVI2VI cvt = cm.add_property_map<VI, VI>(patch_source_name).first; CvtVI2VI cvt = cm.add_property_map<VI, VI>(patch_source_name).first;
// vi_s .. VertexIndex into mesh (source) // vi_s .. VertexIndex into mesh (source)
// vi_d .. new VertexIndex in cm (destination) // vi_d .. new VertexIndex in cm (destination)
for (uint32_t vi_s = 0; vi_s < v_cvt.size(); ++vi_s) { for (VI vi_s : mesh.vertices()) {
uint32_t vi_d = v_cvt[vi_s]; VI vi_d = mesh2result[vi_s];
if (vi_d == def_val) continue; if (!vi_d.is_valid()) continue;
// check only one conversion cvt[vi_d] = vi_s;
assert(!cvt[VI(vi_d)].is_valid());
cvt[VI(vi_d)] = VI(vi_s);
} }
mesh.remove_property_map(mesh2result);
return {std::move(cm)}; return {std::move(cm)};
} }
@ -2458,12 +2455,13 @@ using PatchNumber = CutMesh::Property_map<FI, size_t>;
/// </summary> /// </summary>
/// <param name="n">Order number of patch to separate</param> /// <param name="n">Order number of patch to separate</param>
/// <param name="patch_number">Number for each triangle</param> /// <param name="patch_number">Number for each triangle</param>
/// <param name="patch">Original patch</param> /// <param name="patch">Original patch
/// 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(size_t n,
const PatchNumber &patch_number, const PatchNumber &patch_number,
const SurfacePatch &patch, /* const*/ SurfacePatch &patch,
const CvtVI2VI &cvt_from); const CvtVI2VI &cvt_from);
/// <summary> /// <summary>
@ -2576,7 +2574,7 @@ uint32_t priv::get_shape_point_index(const CutAOI &cut, const CutMesh &model)
priv::SurfacePatch priv::separate_patch(size_t n, priv::SurfacePatch priv::separate_patch(size_t n,
const PatchNumber &patch_number, const PatchNumber &patch_number,
const SurfacePatch &patch, SurfacePatch &patch,
const CvtVI2VI &cvt_from) const CvtVI2VI &cvt_from)
{ {
std::vector<FI> fis; std::vector<FI> fis;
@ -2694,7 +2692,7 @@ priv::SurfacePatches priv::diff_models(VCutAOIs &cuts,
for (size_t cut_index = 0; cut_index < model_cuts.size(); ++cut_index, ++index) { for (size_t cut_index = 0; cut_index < model_cuts.size(); ++cut_index, ++index) {
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 = index;
patch.model_id = model_index; patch.model_id = model_index;
@ -2902,10 +2900,6 @@ SurfaceCut priv::patch2cut(SurfacePatch &patch)
SurfaceCut sc; SurfaceCut sc;
sc.indices.reserve(indices_size); sc.indices.reserve(indices_size);
sc.vertices.reserve(vertices_size); sc.vertices.reserve(vertices_size);
std::vector<uint32_t> v_cvt;
v_cvt.reserve(vertices_size);
for (VI vi : mesh.vertices()) { for (VI vi : mesh.vertices()) {
// vi order is is not sorted // vi order is is not sorted
// assert(vi.idx() == sc.vertices.size()); // assert(vi.idx() == sc.vertices.size());
@ -2944,7 +2938,6 @@ SurfaceCut priv::patch2cut(SurfacePatch &patch)
// Not neccessary, clean and free memory // Not neccessary, clean and free memory
mesh.remove_property_map(convert_map); mesh.remove_property_map(convert_map);
return sc; return sc;
} }