Compare commits

...

10 Commits

  1. 2
      frontend/src/solve.cpp
  2. 4
      network_process/include/post_topo/filter_polygon_faces.hpp
  3. 10
      network_process/src/post_topo/filter_polygon_faces.cpp
  4. 14
      network_process/src/post_topo/patch_propagation.cpp
  5. 1
      network_process/src/prim_gen/filter_tet_by_subface.cpp
  6. 73
      network_process/src/process.cpp
  7. 14
      primitive_process/interface/data/data_type.hpp
  8. 2
      primitive_process/src/primitive/simple/cylinder.cpp

2
frontend/src/solve.cpp

@ -31,7 +31,7 @@ API primitive_generation_result_t generate_polymesh(implicit_network_solver* sol
result.mesh.num_vertices = static_cast<uint32_t>(output_vertices.size());
result.mesh.num_faces = static_cast<uint32_t>(output_vertex_counts_of_face.size());
vector3d* vertices = (vector3d*)mi_malloc(sizeof(vector3d) * result.mesh.num_vertices);
uint32_t* faces = (uint32_t*)mi_malloc(sizeof(uint32_t) * result.mesh.num_faces);
uint32_t* faces = (uint32_t*)mi_malloc(sizeof(uint32_t) * output_polygon_faces.size());
uint32_t* vertex_counts = (uint32_t*)mi_malloc(sizeof(uint32_t) * result.mesh.num_faces);
for (uint32_t i = 0; i < result.mesh.num_vertices; i++) {
std::move(output_vertices[i].data(), output_vertices[i].data() + 3, &vertices[i].x);

4
network_process/include/post_topo/filter_polygon_faces.hpp

@ -13,4 +13,6 @@ dynamic_bitset_mp<> filter_polygon_faces(const stl_vector_mp<polygon_face_t>&
stl_vector_mp<uint32_t>& output_polygon_faces,
stl_vector_mp<uint32_t>& output_vertex_counts_of_face);
void filter_active_vertices(stl_vector_mp<Eigen::Vector3d>& vertices, stl_vector_mp<uint32_t>& output_polygon_faces);
void filter_active_vertices(stl_vector_mp<Eigen::Vector3d>& iso_pts,
stl_vector_mp<Eigen::Vector3d>& vertices,
stl_vector_mp<uint32_t>& output_polygon_faces);

10
network_process/src/post_topo/filter_polygon_faces.cpp

@ -82,10 +82,12 @@ dynamic_bitset_mp<> filter_polygon_faces(const stl_vector_mp<polygon_face_t>&
return active_face_label;
}
void filter_active_vertices(stl_vector_mp<Eigen::Vector3d>& vertices, stl_vector_mp<uint32_t>& output_polygon_faces)
void filter_active_vertices(stl_vector_mp<Eigen::Vector3d>& iso_pts,
stl_vector_mp<Eigen::Vector3d>& output_vertices,
stl_vector_mp<uint32_t>& output_polygon_faces)
{
stl_vector_mp<uint32_t> unique_vertex_indices{};
dynamic_bitset_mp<> vertex_visited(vertices.size(), false);
dynamic_bitset_mp<> vertex_visited(iso_pts.size(), false);
for (const auto& vertex_index : output_polygon_faces) {
if (!vertex_visited[vertex_index]) {
unique_vertex_indices.emplace_back(vertex_index);
@ -102,6 +104,6 @@ void filter_active_vertices(stl_vector_mp<Eigen::Vector3d>& vertices, stl_vector
stl_vector_mp<Eigen::Vector3d> unique_vertices{};
unique_vertices.reserve(unique_vertex_indices.size());
for (const auto& vertex_index : unique_vertex_indices) { unique_vertices.emplace_back(vertices[vertex_index]); }
std::swap(vertices, unique_vertices);
for (const auto& vertex_index : unique_vertex_indices) { unique_vertices.emplace_back(iso_pts[vertex_index]); }
std::swap(output_vertices, unique_vertices);
}

14
network_process/src/post_topo/patch_propagation.cpp

@ -137,9 +137,12 @@ void transform_subface_to_primitive_labels(const baked_blobtree_t&
temp_subface_signs.reserve(subface_indices.size());
for (const auto& subface_index : subface_indices)
temp_subface_signs.emplace_back(cell_subface_signs[subface_index]);
// sign 0 in blobtree means inside, so we need to flip the sign
cell_primitive_sign = primitive.judge_sign_by_subface_sign(temp_subface_signs);
std::cout << "primitive " << i << " sign: " << cell_primitive_sign << std::endl;
for (size_t j = 0; j < cell_primitive_sign.size(); ++j) {
std::cout << " subface sign for cell " << j << ": " << cell_primitive_sign[j] << std::endl;
}
}
}
@ -168,11 +171,11 @@ dynamic_bitset_mp<> filter_cells_by_boolean(const baked_blobtree_t&
const auto& other_cell_sign = stacked_nodes.top().cell_signs;
switch (iter->get_operation()) {
case internal::eNodeOperation::unionOp: temp_info.cell_signs |= other_cell_sign; break;
case internal::eNodeOperation::intersectionOp: temp_info.cell_signs &= other_cell_sign; break;
case internal::eNodeOperation::unionOp: temp_info.cell_signs &= other_cell_sign; break;
case internal::eNodeOperation::intersectionOp: temp_info.cell_signs |= other_cell_sign; break;
case internal::eNodeOperation::differenceOp:
// stacked nodes are always left childs
temp_info.cell_signs.flip() &= other_cell_sign;
temp_info.cell_signs.flip() |= other_cell_sign;
break;
default: throw std::runtime_error("ERROR: baked blobtree with unknown type operation node"); break;
}
@ -187,5 +190,6 @@ dynamic_bitset_mp<> filter_cells_by_boolean(const baked_blobtree_t&
assert(stacked_nodes.size() == 1);
assert(stacked_nodes.top().parent_index == 0xFFFFFFFF);
return stacked_nodes.top().cell_signs;
// sign 0 in blobtree means inside, so we need to flip the sign
return stacked_nodes.top().cell_signs.flip();
}

1
network_process/src/prim_gen/filter_tet_by_subface.cpp

@ -140,6 +140,7 @@ void filter_tet_by_subface(const btree_map_mp<uint32_t, stl_vector_mp<uint32_t>>
filtered_vertex_lexigraphical_adjacency.emplace(vertex_index, vertex_indices_mapping.at(vertex_index));
filtered_vert_infos_iter++;
}
vertex_infos.resize(filtered_vert_infos.rows(), filtered_vert_infos.cols());
vertex_infos = std::move(filtered_vert_infos);
vertex_lexigraphical_adjacency = std::move(filtered_vertex_lexigraphical_adjacency);
}

73
network_process/src/process.cpp

@ -6,18 +6,16 @@
#include <fstream>
void export_halfpatch_obj(
const stl_vector_mp<Eigen::Vector3d>& iso_pts,
const stl_vector_mp<polygon_face_t>& iso_faces,
const stl_vector_mp<stl_vector_mp<uint32_t>>& patches,
const std::string& filename)
void export_halfpatch_obj(const stl_vector_mp<Eigen::Vector3d>& iso_pts,
const stl_vector_mp<polygon_face_t>& iso_faces,
const stl_vector_mp<stl_vector_mp<uint32_t>>& patches,
const std::string& filename)
{
std::string mtl_filename = filename + ".mtl";
std::string mtl_filename = filename + ".mtl";
std::ofstream mtl(mtl_filename);
for (size_t half_patch = 0; half_patch < patches.size() * 2; ++half_patch) {
size_t patch_idx = half_patch / 2;
bool is_forward = (half_patch % 2 == 0);
size_t patch_idx = half_patch / 2;
bool is_forward = (half_patch % 2 == 0);
mtl << "newmtl patch_" << patch_idx << (is_forward ? "_in" : "_out") << "\n";
// 随机或规律分配颜色
float r = float(patch_idx % 7) / 7.0f;
@ -27,32 +25,28 @@ void export_halfpatch_obj(
}
mtl.close();
std::string obj_filename = filename + ".obj";
std::string obj_filename = filename + ".obj";
std::ofstream ofs(obj_filename);
if (!ofs) return;
ofs << "mtllib "<< mtl_filename << "\n";
ofs << "mtllib " << mtl_filename << "\n";
// 输出所有顶点
for (const auto& v : iso_pts) {
ofs << "v " << v.x() << " " << v.y() << " " << v.z() << "\n";
}
for (const auto& v : iso_pts) { ofs << "v " << v.x() << " " << v.y() << " " << v.z() << "\n"; }
// 遍历所有 half-patch
for (size_t half_patch = 0; half_patch < patches.size() * 2; ++half_patch) {
size_t patch_idx = half_patch / 2;
bool is_forward = (half_patch % 2 == 0);
size_t patch_idx = half_patch / 2;
bool is_forward = (half_patch % 2 == 0);
ofs << "g halfpatch_" << half_patch << "\n";
ofs << "usemtl patch_" << patch_idx << (is_forward ? "_in" : "_out") << "\n";
for (auto face_idx : patches[patch_idx]) {
const auto& face = iso_faces[face_idx];
ofs << "f";
if (is_forward) {
for (auto vi : face.vertex_indices)
ofs << " " << (vi + 1);
for (auto vi : face.vertex_indices) ofs << " " << (vi + 1);
} else {
for (auto it = face.vertex_indices.rbegin(); it != face.vertex_indices.rend(); ++it)
ofs << " " << (*it + 1);
for (auto it = face.vertex_indices.rbegin(); it != face.vertex_indices.rend(); ++it) ofs << " " << (*it + 1);
}
ofs << "\n";
}
@ -60,6 +54,33 @@ void export_halfpatch_obj(
ofs.close();
}
void export_obj(const stl_vector_mp<Eigen::Vector3d>& vertices,
stl_vector_mp<uint32_t>& faces,
stl_vector_mp<uint32_t>& output_vertex_counts_of_face,
const std::string& filename)
{
std::string obj_filename = filename + ".obj";
std::ofstream ofs(obj_filename);
if (!ofs) return;
// 输出所有顶点
for (const auto& v : vertices) { ofs << "v " << v.x() << " " << v.y() << " " << v.z() << "\n"; }
// 输出所有面
// 输出所有面
size_t idx = 0;
for (auto count : output_vertex_counts_of_face) {
ofs << "f";
for (size_t i = 0; i < count; ++i) {
ofs << " " << (faces[idx++] + 1); // OBJ 索引从1开始
}
ofs << "\n";
}
ofs.close();
ofs.close();
}
ISNP_API void build_implicit_network_by_blobtree(const s_settings& settings,
const baked_blobtree_t& tree,
@ -164,7 +185,7 @@ ISNP_API void build_implicit_network_by_blobtree(const s_settings&
{
arrangement_cells.reserve(shells.size());
for (uint32_t i = 0; i < shells.size(); ++i) { arrangement_cells.emplace_back(stl_vector_mp<uint32_t>{i}); }
} else {
{
stl_vector_mp<std::pair<uint32_t, uint32_t>> shell_links{};
@ -208,6 +229,10 @@ ISNP_API void build_implicit_network_by_blobtree(const s_settings&
transform_subface_to_primitive_labels(tree, cell_subface_signs, cell_primitive_signs);
}
active_cell_label = filter_cells_by_boolean(tree, cell_primitive_signs);
for (uint32_t i = 0; i < arrangement_cells.size(); ++i) {
std::cout << "Cell " << i << " active: " << active_cell_label[i] << std::endl;
}
}
filter_polygon_faces(iso_faces,
patches,
@ -218,10 +243,8 @@ ISNP_API void build_implicit_network_by_blobtree(const s_settings&
active_cell_label,
output_polygon_faces,
output_vertex_counts_of_face);
filter_active_vertices(output_vertices, output_polygon_faces);
export_halfpatch_obj(iso_pts, iso_faces, patches, "halfpatch_final");
filter_active_vertices(iso_pts, output_vertices, output_polygon_faces);
export_obj(output_vertices, output_polygon_faces,output_vertex_counts_of_face,"final");
}
}
}

14
primitive_process/interface/data/data_type.hpp

@ -25,7 +25,17 @@ const auto plane_to_z_pos_1_model_matrix = []() {
res.world_to_local.linear().col(2) = Eigen::Vector3d{1, 0, 0};
res.world_to_local.translation() = Eigen::Vector3d{-1, 0, 0};
res.local_to_world = res.world_to_local;
res.local_to_world.translation() = Eigen::Vector3d{1, 0, 0};
res.local_to_world.translation() = Eigen::Vector3d{0, 0, 1};
return res;
}();
const auto plane_to_z_model_matrix = []() {
paired_model_matrix res{};
Eigen::Matrix3d::Identity();
res.world_to_local.linear().col(0) = Eigen::Vector3d{0, 0, 1};
res.world_to_local.linear().col(1) = Eigen::Vector3d{0, 1, 0};
res.world_to_local.linear().col(2) = Eigen::Vector3d{1, 0, 0};
res.world_to_local.translation() = Eigen::Vector3d{0, 0, 0};
res.local_to_world = res.world_to_local;
return res;
}();
const auto plane_to_z_neg_1_model_matrix = []() {
@ -35,7 +45,7 @@ const auto plane_to_z_neg_1_model_matrix = []() {
res.world_to_local.linear().col(2) = Eigen::Vector3d{1, 0, 0};
res.world_to_local.translation() = Eigen::Vector3d{1, 0, 0};
res.local_to_world = res.world_to_local;
res.local_to_world.translation() = Eigen::Vector3d{-1, 0, 0};
res.local_to_world.translation() = Eigen::Vector3d{0, 0, -1};
return res;
}();

2
primitive_process/src/primitive/simple/cylinder.cpp

@ -4,7 +4,7 @@ namespace internal
{
void cylinder_t::initialize(primitive_data_center_t &data_center)
{
auto [bottom_plane_iter, _] = data_center.transform_blocks.acquire(internal::plane_to_z_neg_1_model_matrix);
auto [bottom_plane_iter, _] = data_center.transform_blocks.acquire(internal::plane_to_z_model_matrix);
auto [cylinder_iter, __] = data_center.transform_blocks.acquire(internal::identity_model_matrix);
auto [top_plane_iter, ___] = data_center.transform_blocks.acquire(internal::plane_to_z_pos_1_model_matrix);
initialize(data_center,

Loading…
Cancel
Save