Browse Source

fixed bugs in add_plane, now arrangement can be built successfully;

fixed an index bug in generating tet mesh;
simplified storage of scalar field sign, now it has lower memory consume and can work properly
pull/1/head
ZCWang 7 months ago
parent
commit
5cba1ba952
  1. 1
      implicit_arrangements/include/arrangement_builder.hpp
  2. 3
      implicit_arrangements/src/add_plane.cpp
  3. 16
      network_process/src/background_mesh.cpp
  4. 38
      network_process/src/implicit_surface_network_processor.cpp

1
implicit_arrangements/include/arrangement_builder.hpp

@ -140,7 +140,6 @@ public:
unique_plane_count++; unique_plane_count++;
} }
} }
std::cout << "test" << std::endl;
m_arrangement.arrangement = extract_arrangement(std::move(ia_complex)); m_arrangement.arrangement = extract_arrangement(std::move(ia_complex));
m_arrangement.is_runtime_computed = true; m_arrangement.is_runtime_computed = true;

3
implicit_arrangements/src/add_plane.cpp

@ -1,5 +1,4 @@
#include <algorithm/glue_algorithm.hpp> #include <algorithm/glue_algorithm.hpp>
#include <iostream>
#include "ia_cut_face.hpp" #include "ia_cut_face.hpp"
#include "robust_assert.hpp" #include "robust_assert.hpp"
@ -17,7 +16,6 @@ inline void shrink(small_vector_mp<T>& c, small_vector_mp<uint32_t>& index_map,
index_map[i] = active_count; index_map[i] = active_count;
active_count++; active_count++;
} }
std::cout << "shrink: " << s << " -> " << active_count << std::endl;
c.resize(active_count); c.resize(active_count);
} }
@ -236,7 +234,6 @@ uint32_t add_plane(const PlaneGroup<3>& repo, IAComplex<3>& ia_complex, uint32_t
// Step 7: remove unused geometries. // Step 7: remove unused geometries.
remove_unused_geometry(ia_complex); remove_unused_geometry(ia_complex);
std::cout << "an add_plane() completed" << std::endl;
return coplanar_plane; return coplanar_plane;
} }

16
network_process/src/background_mesh.cpp

@ -31,7 +31,7 @@ tetrahedron_mesh_t generate_tetrahedron_background_mesh(uint32_t
const auto v0 = i * N * N + j * N + k; const auto v0 = i * N * N + j * N + k;
mesh.vertices[v0] = {x, y, z}; mesh.vertices[v0] = {x, y, z};
if (i < resolution - 1 && j < resolution - 1 && k < resolution - 1) { if (i < resolution && j < resolution && k < resolution) {
size_t idx = (i * resolution * resolution + j * resolution + k) * 5; size_t idx = (i * resolution * resolution + j * resolution + k) * 5;
const auto v1 = (i + 1) * N * N + j * N + k; const auto v1 = (i + 1) * N * N + j * N + k;
const auto v2 = (i + 1) * N * N + (j + 1) * N + k; const auto v2 = (i + 1) * N * N + (j + 1) * N + k;
@ -42,11 +42,17 @@ tetrahedron_mesh_t generate_tetrahedron_background_mesh(uint32_t
const auto v7 = i * N * N + (j + 1) * N + k + 1; const auto v7 = i * N * N + (j + 1) * N + k + 1;
if ((i + j + k) % 2 == 0) if ((i + j + k) % 2 == 0)
*(TetrahedronVertexIndexGroup*)(mesh.indices.data() + idx) = {v4, v6, v1, v3, v6, v3, v4, v7, v1, v3, *(TetrahedronVertexIndexGroup*)(mesh.indices.data() + idx) = {v4, v6, v1, v3, //
v0, v4, v3, v1, v2, v6, v4, v1, v6, v5}; v6, v3, v4, v7, //
v1, v3, v0, v4, //
v3, v1, v2, v6, //
v4, v1, v6, v5};
else else
*(TetrahedronVertexIndexGroup*)(mesh.indices.data() + idx) = {v7, v0, v2, v5, v2, v3, v0, v7, v5, v7, *(TetrahedronVertexIndexGroup*)(mesh.indices.data() + idx) = {v7, v0, v2, v5, //
v0, v4, v7, v2, v6, v5, v0, v1, v2, v5}; v2, v3, v0, v7, //
v5, v7, v0, v4, //
v7, v2, v6, v5, //
v0, v1, v2, v5};
} }
}); });
} }

38
network_process/src/implicit_surface_network_processor.cpp

@ -15,15 +15,19 @@ bool ImplicitSurfaceNetworkProcessor::run(labelled_timers_manager& timers_manage
const auto num_funcs = sdf_scalar_field.rows(); const auto num_funcs = sdf_scalar_field.rows();
// compute function signs at vertices // compute function signs at vertices
// EDIT: we only need to identify the sdf value is inside or on surface/outside
// Eigen::Matrix<int8_t, Eigen::Dynamic, Eigen::Dynamic> scalar_field_signs(num_funcs, num_vert);
auto scalar_field_sign = [](double x) -> int8_t { return (x > 0) ? 1 : ((x < 0) ? -1 : 0); }; auto scalar_field_sign = [](double x) -> int8_t { return (x > 0) ? 1 : ((x < 0) ? -1 : 0); };
Eigen::MatrixXd scalar_field_signs(num_funcs, num_vert); dynamic_bitset_mp<> is_positive_scalar_field_sign(num_funcs * num_vert, false);
dynamic_bitset_mp<> is_negative_scalar_field_sign(num_funcs * num_vert, false);
dynamic_bitset_mp<> is_degenerate_vertex(num_vert, false); dynamic_bitset_mp<> is_degenerate_vertex(num_vert, false);
{ {
timers_manager.push_timer("identify sdf signs"); timers_manager.push_timer("identify sdf signs");
for (size_t i = 0; i < sdf_scalar_field.size(); ++i) { for (size_t i = 0; i < sdf_scalar_field.size(); ++i) {
if ((*(scalar_field_signs.data() + i) = scalar_field_sign(*(sdf_scalar_field.data() + i))) == 0) { const auto sign = scalar_field_sign(*(sdf_scalar_field.data() + i));
is_degenerate_vertex.set(i); is_positive_scalar_field_sign.set(i, sign > 0);
} is_negative_scalar_field_sign.set(i, sign < 0);
if (sign == 0) { is_degenerate_vertex.set(i); }
} }
timers_manager.pop_timer("identify sdf signs"); timers_manager.pop_timer("identify sdf signs");
} }
@ -41,11 +45,14 @@ bool ImplicitSurfaceNetworkProcessor::run(labelled_timers_manager& timers_manage
for (Eigen::Index i = 0; i < num_tets; ++i) { for (Eigen::Index i = 0; i < num_tets; ++i) {
const auto tet_ptr = &background_mesh.indices[i].v1; const auto tet_ptr = &background_mesh.indices[i].v1;
for (Eigen::Index j = 0; j < num_funcs; ++j) { for (Eigen::Index j = 0; j < num_funcs; ++j) {
uint32_t pos_count{}; uint32_t pos_count{}, neg_count{};
for (uint32_t k = 0; k < 4; ++k) for (uint32_t k = 0; k < 4; ++k) {
if (scalar_field_signs(j, tet_ptr[k]) == 1) pos_count++; if (is_positive_scalar_field_sign[tet_ptr[k] * num_funcs + j]) pos_count++;
if (is_negative_scalar_field_sign[tet_ptr[k] * num_funcs + j]) neg_count++;
}
// if (scalar_field_signs(j, tet_ptr[k]) == 1) pos_count++;
// tets[i].size() == 4, this means that the function is active in this tet // tets[i].size() == 4, this means that the function is active in this tet
if (0 < pos_count && pos_count < 4) func_in_tet.emplace_back(j); if (pos_count < 4 && neg_count < 4) func_in_tet.emplace_back(j);
} }
if (func_in_tet.size() > start_index_of_tet.back()) { ++num_intersecting_tet; } if (func_in_tet.size() > start_index_of_tet.back()) { ++num_intersecting_tet; }
start_index_of_tet.emplace_back(static_cast<uint32_t>(func_in_tet.size())); start_index_of_tet.emplace_back(static_cast<uint32_t>(func_in_tet.size()));
@ -114,7 +121,6 @@ bool ImplicitSurfaceNetworkProcessor::run(labelled_timers_manager& timers_manage
} }
timers_manager.pop_timer("implicit arrangements calculation in total"); timers_manager.pop_timer("implicit arrangements calculation in total");
} }
std::cout << "test" << std::endl;
// extract arrangement mesh: combining results from all tets to produce a mesh // extract arrangement mesh: combining results from all tets to produce a mesh
stl_vector_mp<IsoVertex> iso_verts{}; stl_vector_mp<IsoVertex> iso_verts{};
@ -287,16 +293,22 @@ bool ImplicitSurfaceNetworkProcessor::run(labelled_timers_manager& timers_manage
} }
// fetching function labels (True, False) for each cell // fetching function labels (True, False) for each cell
small_dynamic_bitset_mp<> sample_function_label(num_funcs); small_dynamic_bitset_mp<> sample_function_label{};
for (Eigen::Index i = 0; i < num_funcs; i++) { sample_function_label.reserve(num_funcs);
sample_function_label.set(i, (scalar_field_signs(0, i) == 1) ? true : false); sample_function_label.append(is_positive_scalar_field_sign.data(),
} is_positive_scalar_field_sign.data() + num_funcs / sizeof(size_t) + 1);
// for (size_t i = 0; i < num_funcs; i++) {
// // sample_function_label.set(i, (scalar_field_signs(i, size_t{0}) == 1) ? true : false);
// sample_function_label.set(i, scalar_field_signs[i]);
// }
std::cout << "test" << std::endl;
cell_function_labels = sign_propagation(arrangement_cells, cell_function_labels = sign_propagation(arrangement_cells,
shell_of_half_patch, shell_of_half_patch,
shells, shells,
patch_function_labels, patch_function_labels,
num_funcs, num_funcs,
sample_function_label); sample_function_label);
std::cout << "test" << std::endl;
// free Arranger3D runtime memory iff necessary // free Arranger3D runtime memory iff necessary
for (uint32_t i = 0; i < cut_results.size(); ++i) { for (uint32_t i = 0; i < cut_results.size(); ++i) {

Loading…
Cancel
Save