Browse Source

temporary push

V2
Zhicheng Wang 3 days ago
parent
commit
c36797d8ba
  1. 11
      network_process/interface/fwd_types.hpp
  2. 9
      network_process/interface/process.hpp
  3. 214
      network_process/src/post_topo/filter_polygon_faces.cpp

11
network_process/interface/fwd_types.hpp

@ -206,6 +206,17 @@ struct polygon_face_t {
// ==============================================================================
// each active subface should have one structure as below
struct parametric_plane {
stl_vector_mp<Eigen::Vector2d> chain_vertices{};
flat_index_group chains{};
stl_vector_mp<uint32_t> singularity_vertices{}; // i.e. intersection of chains
stl_vector_mp<uint32_t> polar_vertices{}; // i.e. min/max x/y around 2 connecting vertices
stl_vector_mp<uint32_t> parallel_start_vertices{}; // i.e. edge {v, v + 1} is parallel to x/y axis
};
// ==============================================================================
namespace std
{
template <>

9
network_process/interface/process.hpp

@ -4,15 +4,6 @@
#include "settings.h"
// each active subface should have one structure as below
struct parametric_plane {
stl_vector_mp<Eigen::Vector2d> chain_vertices{};
flat_index_group chains{};
stl_vector_mp<uint32_t> singularity_vertices{}; // i.e. intersection of chains
stl_vector_mp<uint32_t> polar_vertices{}; // i.e. min/max x/y around 2 connecting vertices
stl_vector_mp<uint32_t> parallel_start_vertices{}; // i.e. edge {v, v + 1} is parallel to x/y axis
};
ISNP_API void build_implicit_network_by_blobtree(const s_settings& settings,
const baked_blobtree_t& tree,
stl_vector_mp<Eigen::Vector3d>& output_vertices,

214
network_process/src/post_topo/filter_polygon_faces.cpp

@ -4,16 +4,15 @@
// ===========================================================================================================
void collect_active_prims(const flat_index_group& patches,
const flat_index_group& chain_of_patch,
const flat_index_group& arrangement_cells,
void collect_active_prims(const flat_index_group& patches,
const flat_index_group& chain_of_patch,
const flat_index_group& arrangement_cells,
const stl_vector_mp<uint32_t>& shell_of_half_patch,
const flat_index_group& shells,
const flat_index_group& shells,
const stl_vector_mp<uint32_t>& shell_to_cell,
const dynamic_bitset_mp<>& active_cell_label,
dynamic_bitset_mp<>& active_patch_label,
dynamic_bitset_mp<>& patch_sign_label,
dynamic_bitset_mp<>& active_chain_label)
dynamic_bitset_mp<>& patch_sign_label)
{
stl_vector_mp<bool> visited_cells(arrangement_cells.size(), false);
std::queue<uint32_t> Q{};
@ -36,10 +35,6 @@ void collect_active_prims(const flat_index_group& patches,
active_patch_label[patch_index].flip();
patch_sign_label[patch_index] = ((half_patch_index & 1) == 0);
chain_of_patch.loop_on_group(patch_index, [&](uint32_t _, uint32_t chain_index) {
active_chain_label[chain_index].set();
});
auto oppose_cell = shell_to_cell[shell_of_half_patch[(half_patch_index & 1) == 1 ? (half_patch_index + 1)
: (half_patch_index - 1)]];
if (active_cell_label[oppose_cell] && !visited_cells[oppose_cell]) Q.emplace(oppose_cell);
@ -49,89 +44,140 @@ void collect_active_prims(const flat_index_group& patches,
}
}
// ===========================================================================================================
dynamic_bitset_mp<> filter_polygon_faces(const stl_vector_mp<polygon_face_t>& faces,
const flat_index_group& patches,
const flat_index_group& arrangement_cells,
const stl_vector_mp<uint32_t>& shell_of_half_patch,
const flat_index_group& shells,
const stl_vector_mp<uint32_t>& shell_to_cell,
const dynamic_bitset_mp<>& active_cell_label,
stl_vector_mp<uint32_t>& output_polygon_faces,
stl_vector_mp<uint32_t>& output_vertex_counts_of_face)
void transfer_active_prims(const stl_vector_mp<polygon_face_t>& faces,
const flat_index_group& patches,
const flat_index_group& chain_of_patch,
const dynamic_bitset_mp<>& active_patch_label,
const dynamic_bitset_mp<>& patch_sign_label,
stl_vector_mp<uint32_t>& output_polygon_faces,
stl_vector_mp<uint32_t>& output_vertex_counts_of_face,
stl_vector_mp<parametric_plane>& output_parametric_planes)
{
dynamic_bitset_mp<> active_face_label(faces.size(), false);
dynamic_bitset_mp<> active_patch_label(patches.size(), false);
dynamic_bitset_mp<> patch_sign_label(patches.size(), false);
output_polygon_faces.reserve(faces.size() * 3);
output_vertex_counts_of_face.reserve(faces.size());
auto active_patch_index = active_patch_label.find_first();
if (active_patch_index != dynamic_bitset_mp<>::npos) {
do {
// NOTE: since patch inside the sdf should be oriented counterclockwise when viewed from inside
// i.e. it is viewed to be clockwise when viewed from outside
// so we need to flip its vertex order here
// NOTE: as for the integral, surface integral is always positive so we just add them up
// however for the partial volume integral, the right one should be corresponding to the normal which
// points outside. Here's a simple prove that the partial volume integral always have right sign: If the
// surface is outside (i.e. counterclockwise), then it is obviously right; If the surface is inside
// (i.e. clockwise), then its normal should point to the other side of that surface, which is the
// outside of that surface, so it is also right
if (!patch_sign_label[active_patch_index]) {
patches.loop_on_group(active_patch_index, [&](uint32_t _, uint32_t face_index) {
const auto& face_vertices = faces[face_index].vertex_indices;
output_vertex_counts_of_face.emplace_back(face_vertices.size());
output_polygon_faces.insert(output_polygon_faces.end(),
std::make_move_iterator(face_vertices.rbegin()),
std::make_move_iterator(face_vertices.rend()));
});
} else {
patches.loop_on_group(active_patch_index, [&](uint32_t _, uint32_t face_index) {
const auto& face_vertices = faces[face_index].vertex_indices;
output_vertex_counts_of_face.emplace_back(face_vertices.size());
output_polygon_faces.insert(output_polygon_faces.end(),
std::make_move_iterator(face_vertices.begin()),
std::make_move_iterator(face_vertices.end()));
});
}
stl_vector_mp<bool> visited_cells(arrangement_cells.size(), false);
std::queue<uint32_t> Q{};
for (uint32_t i = 0; i < arrangement_cells.size(); ++i) {
if (active_cell_label[i]) {
Q.emplace(i);
break;
}
}
while (!Q.empty()) {
const auto cell_index = Q.front();
Q.pop();
chain_of_patch.loop_on_group(active_patch_index,
[&](uint32_t _, uint32_t chain_index) { active_chain_label[chain_index].set(); });
if (!visited_cells[cell_index] && active_cell_label[cell_index]) {
visited_cells[cell_index] = true;
arrangement_cells.loop_on_group(cell_index, [&](uint32_t _, uint32_t shell_index) {
// it is secured that one shell cell cannot have a pair of half patches with same patch index
shells.loop_on_group(shell_index, [&](uint32_t _, uint32_t half_patch_index) {
bool sign = (half_patch_index % 2 == 0) ? 0 : 1;
auto oppose_cell =
shell_to_cell[shell_of_half_patch[!sign ? (half_patch_index + 1) : (half_patch_index - 1)]];
// iff not interior patch, we do surface propagation
if (!active_cell_label[oppose_cell]) {
// NOTE: since patch inside the sdf should be oriented counterclockwise when viewed from inside
// i.e. it is viewed to be clockwise when viewed from outside
// so we need to flip its vertex order here
// NOTE: as for the integral, surface integral is always positive so we just add them up
// however for the partial volume integral, the right one should be corresponding to the normal which
// points outside. Here's a simple prove that the partial volume integral always have right sign: If the
// surface is outside (i.e. counterclockwise), then it is obviously right; If the surface is inside
// (i.e. clockwise), then its normal should point to the other side of that surface, which is the
// outside of that surface, so it is also right
if (!sign) {
patches.loop_on_group(half_patch_index / 2, [&](uint32_t _, uint32_t face_index) {
active_face_label[face_index] = true;
const auto& face_vertices = faces[face_index].vertex_indices;
output_vertex_counts_of_face.emplace_back(face_vertices.size());
output_polygon_faces.insert(output_polygon_faces.end(),
std::make_move_iterator(face_vertices.rbegin()),
std::make_move_iterator(face_vertices.rend()));
});
} else {
patches.loop_on_group(half_patch_index / 2, [&](uint32_t _, uint32_t face_index) {
active_face_label[face_index] = true;
const auto& face_vertices = faces[face_index].vertex_indices;
output_vertex_counts_of_face.emplace_back(face_vertices.size());
output_polygon_faces.insert(output_polygon_faces.end(),
std::make_move_iterator(face_vertices.begin()),
std::make_move_iterator(face_vertices.end()));
});
}
} else if (!visited_cells[oppose_cell]) {
// active and not visited cell, enqueue it
Q.emplace(oppose_cell);
}
});
});
}
active_patch_index = active_patch_label.find_next(active_patch_index);
} while (active_patch_index != dynamic_bitset_mp<>::npos);
}
output_polygon_faces.shrink_to_fit();
output_vertex_counts_of_face.shrink_to_fit();
return active_face_label;
}
// ===========================================================================================================
// dynamic_bitset_mp<> filter_polygon_faces(const stl_vector_mp<polygon_face_t>& faces,
// const flat_index_group& patches,
// const flat_index_group& arrangement_cells,
// const stl_vector_mp<uint32_t>& shell_of_half_patch,
// const flat_index_group& shells,
// const stl_vector_mp<uint32_t>& shell_to_cell,
// const dynamic_bitset_mp<>& active_cell_label,
// stl_vector_mp<uint32_t>& output_polygon_faces,
// stl_vector_mp<uint32_t>& output_vertex_counts_of_face)
// {
// dynamic_bitset_mp<> active_face_label(faces.size(), false);
// dynamic_bitset_mp<> active_patch_label(patches.size(), false);
// dynamic_bitset_mp<> patch_sign_label(patches.size(), false);
// output_polygon_faces.reserve(faces.size() * 3);
// output_vertex_counts_of_face.reserve(faces.size());
// stl_vector_mp<bool> visited_cells(arrangement_cells.size(), false);
// std::queue<uint32_t> Q{};
// for (uint32_t i = 0; i < arrangement_cells.size(); ++i) {
// if (active_cell_label[i]) {
// Q.emplace(i);
// break;
// }
// }
// while (!Q.empty()) {
// const auto cell_index = Q.front();
// Q.pop();
// if (!visited_cells[cell_index] && active_cell_label[cell_index]) {
// visited_cells[cell_index] = true;
// arrangement_cells.loop_on_group(cell_index, [&](uint32_t _, uint32_t shell_index) {
// // it is secured that one shell cell cannot have a pair of half patches with same patch index
// shells.loop_on_group(shell_index, [&](uint32_t _, uint32_t half_patch_index) {
// bool sign = (half_patch_index % 2 == 0) ? 0 : 1;
// auto oppose_cell =
// shell_to_cell[shell_of_half_patch[!sign ? (half_patch_index + 1) : (half_patch_index - 1)]];
// // iff not interior patch, we do surface propagation
// if (!active_cell_label[oppose_cell]) {
// // NOTE: since patch inside the sdf should be oriented counterclockwise when viewed from inside
// // i.e. it is viewed to be clockwise when viewed from outside
// // so we need to flip its vertex order here
// // NOTE: as for the integral, surface integral is always positive so we just add them up
// // however for the partial volume integral, the right one should be corresponding to the normal which
// // points outside. Here's a simple prove that the partial volume integral always have right sign: If
// the
// // surface is outside (i.e. counterclockwise), then it is obviously right; If the surface is inside
// // (i.e. clockwise), then its normal should point to the other side of that surface, which is the
// // outside of that surface, so it is also right
// if (!sign) {
// patches.loop_on_group(half_patch_index / 2, [&](uint32_t _, uint32_t face_index) {
// active_face_label[face_index] = true;
// const auto& face_vertices = faces[face_index].vertex_indices;
// output_vertex_counts_of_face.emplace_back(face_vertices.size());
// output_polygon_faces.insert(output_polygon_faces.end(),
// std::make_move_iterator(face_vertices.rbegin()),
// std::make_move_iterator(face_vertices.rend()));
// });
// } else {
// patches.loop_on_group(half_patch_index / 2, [&](uint32_t _, uint32_t face_index) {
// active_face_label[face_index] = true;
// const auto& face_vertices = faces[face_index].vertex_indices;
// output_vertex_counts_of_face.emplace_back(face_vertices.size());
// output_polygon_faces.insert(output_polygon_faces.end(),
// std::make_move_iterator(face_vertices.begin()),
// std::make_move_iterator(face_vertices.end()));
// });
// }
// } else if (!visited_cells[oppose_cell]) {
// // active and not visited cell, enqueue it
// Q.emplace(oppose_cell);
// }
// });
// });
// }
// }
// output_polygon_faces.shrink_to_fit();
// output_vertex_counts_of_face.shrink_to_fit();
// return active_face_label;
// }
void filter_active_vertices(stl_vector_mp<Eigen::Vector3d>& vertices, stl_vector_mp<uint32_t>& output_polygon_faces)
{
stl_vector_mp<uint32_t> unique_vertex_indices{};

Loading…
Cancel
Save