From 585c8b700a91d04f39a344c8820b3073fdb32c70 Mon Sep 17 00:00:00 2001 From: Zhicheng Wang <1627343141@qq.com> Date: Tue, 18 Nov 2025 10:46:43 +0800 Subject: [PATCH] fix known issue caused by chain cycle --- network_process/interface/fwd_types.hpp | 12 ++-- network_process/src/post_topo/map_chains.cpp | 69 ++++++++++++++------ primitive_process/interface/base/subface.hpp | 3 + primitive_process/src/base/subface.cpp | 11 ++++ shared_module/math/math_defs.hpp | 2 + 5 files changed, 72 insertions(+), 25 deletions(-) diff --git a/network_process/interface/fwd_types.hpp b/network_process/interface/fwd_types.hpp index 11e978c..9f0938c 100644 --- a/network_process/interface/fwd_types.hpp +++ b/network_process/interface/fwd_types.hpp @@ -100,12 +100,12 @@ struct vertex_header_t { struct iso_vertex_t { vertex_header_t header{}; std::array simplex_vertex_indices{}; /// ? index into a list of tet vertices - std::array subface_indices = { - short_invalid_index, - short_invalid_index, - short_invalid_index}; /// list of subfaces whose isosurfaces pass IsoVert (indexed into a global list of - /// subfaces) - /// so current solution only supports at most 3 iso-surfaces passing through a vertex? + // std::array subface_indices = { + // short_invalid_index, + // short_invalid_index, + // short_invalid_index}; /// list of subfaces whose isosurfaces pass IsoVert (indexed into a global list of + // /// subfaces) + // /// so current solution only supports at most 3 iso-surfaces passing through a vertex? }; // given the list of vertex indices of a face, return the unique key of the face: (the smallest vert Id, diff --git a/network_process/src/post_topo/map_chains.cpp b/network_process/src/post_topo/map_chains.cpp index 7442f85..4be9009 100644 --- a/network_process/src/post_topo/map_chains.cpp +++ b/network_process/src/post_topo/map_chains.cpp @@ -27,12 +27,13 @@ void map_chain_to_parametric_plane(const baked_blobtree_t& const auto subface_index = subface_index_; const auto subface_ptr = subfaces[subface_index]; const auto subface_type = subface_types[subface_index]; - auto mapping_func = std::bind(internal::get_map_point_to_param_ptr(subface_type), subface_ptr, std::placeholders::_1); - auto& parametric_plane = parametric_planes[subface_index]; - auto& chain_vertices = parametric_plane.chain_vertices; - auto& chain_group_indices = parametric_plane.chain_group_indices; - auto& chain_vertex_flags = parametric_plane.vertex_special_flags; - auto& chain_other_subface_indices = parametric_plane.chain_other_subface_indices; + auto mapping_func = std::bind(internal::get_map_point_to_param_ptr(subface_type), subface_ptr, std::placeholders::_1); + const auto cycle = internal::get_cycle(subface_type); + auto& parametric_plane = parametric_planes[subface_index]; + auto& chain_vertices = parametric_plane.chain_vertices; + auto& chain_group_indices = parametric_plane.chain_group_indices; + auto& chain_vertex_flags = parametric_plane.vertex_special_flags; + auto& chain_other_subface_indices = parametric_plane.chain_other_subface_indices; chain_group_indices.reserve(patch_indices.size()); unique_chain_indices.clear(); @@ -42,16 +43,19 @@ void map_chain_to_parametric_plane(const baked_blobtree_t& unique_chain_indices.insert(unique_chain_indices.end(), chain_indices.begin(), chain_indices.end()); } std::sort(unique_chain_indices.begin(), unique_chain_indices.end()); - unique_end_iter = std::unique(unique_chain_indices.begin(), unique_chain_indices.end()); - for (auto iter = unique_chain_indices.begin(); iter != unique_end_iter; ++iter) - old_chain_index_to_unique_index[*iter] = std::distance(unique_chain_indices.begin(), iter); - + unique_end_iter = std::unique(unique_chain_indices.begin(), unique_chain_indices.end()); const auto unique_chain_count = std::distance(unique_chain_indices.begin(), unique_end_iter); + for (uint32_t i = 0; i < unique_chain_count; ++i) { + const auto& chain_index = unique_chain_indices[i]; + old_chain_index_to_unique_index[chain_index] = i; + } + chain_vertices.reserve(unique_chain_count); chain_vertex_flags.reserve(unique_chain_count); chain_other_subface_indices.reserve(unique_chain_count); - for (const auto& chain_index : unique_chain_indices) { - const auto& chain = chains[chain_index]; + for (auto iter = unique_chain_indices.begin(); iter != unique_end_iter; ++iter) { + const auto chain_index = *iter; + const auto& chain = chains[chain_index]; auto& chain_vertices_ = chain_vertices.emplace_back(); chain_vertices_.resize(chain.size()); @@ -72,6 +76,33 @@ void map_chain_to_parametric_plane(const baked_blobtree_t& chain_other_subface_indices.emplace_back(other_subface_index); } + // handle chain vertices that cross cycle boundary + // it is assumed that cycle is in U direction, and happens at U = 0 + if (cycle < std::numeric_limits::infinity()) { + int32_t cycle_offset{}; + const auto& world_to_local = subface_ptr->world_to_local; + auto unique_chain_index_iter = unique_chain_indices.begin(); + auto chain_vertex_iter = chain_vertices.begin(); + for (; unique_chain_index_iter != unique_end_iter; ++unique_chain_index_iter, ++chain_vertex_iter) { + const auto& chain_index = *unique_chain_index_iter; + const auto& chain = chains[chain_index]; + auto& chain_verts = *chain_vertex_iter; + for (uint32_t i = 1; i < chain_verts.size(); ++i) { + auto world_position1 = vertices[vertex_old_index_to_unique_index.at(chain[i - 1])]; + auto world_position2 = vertices[vertex_old_index_to_unique_index.at(chain[i])]; + auto local_position1 = world_to_local.linear() * world_position1 + world_to_local.translation(); + auto local_position2 = world_to_local.linear() * world_position2 + world_to_local.translation(); + if (local_position1.x() >= 0 && local_position2.x() >= 0) { + if (local_position1.y() <= 0 && local_position2.y() > 0) + ++cycle_offset; + else if (local_position1.y() > 0 && local_position2.y() <= 0) + --cycle_offset; + } + chain_verts[i].x() += cycle * cycle_offset; + } + } + } + for (const auto& patch_index : patch_indices) { const auto& chain_indices = chain_of_patch.at(patch_index); auto& chain_group = chain_group_indices.emplace_back(); @@ -91,12 +122,12 @@ void remap_parametric_plane_vertices(flat_hash_map_mp epsilon); - const auto uv_bounds_rpc = uv_bounds.sizes().cwiseInverse().array(); - for (auto& chain_vertices : parametric_plane.chain_vertices) { - std::transform(chain_vertices.begin(), - chain_vertices.end(), - chain_vertices.begin(), - [&](const Eigen::Vector2d& uv) { return (uv - uv_bounds.min()).array() * uv_bounds_rpc; }); - } + // const auto uv_bounds_rpc = uv_bounds.sizes().cwiseInverse().array(); + // for (auto& chain_vertices : parametric_plane.chain_vertices) { + // std::transform(chain_vertices.begin(), + // chain_vertices.end(), + // chain_vertices.begin(), + // [&](const Eigen::Vector2d& uv) { return (uv - uv_bounds.min()).array() * uv_bounds_rpc; }); + // } } } \ No newline at end of file diff --git a/primitive_process/interface/base/subface.hpp b/primitive_process/interface/base/subface.hpp index 785bba3..d9985ff 100644 --- a/primitive_process/interface/base/subface.hpp +++ b/primitive_process/interface/base/subface.hpp @@ -95,4 +95,7 @@ def_export_get_function_ptr(eval_dv_constraint); def_export_get_function_ptr(eval_intersection); #undef def_export_get_function_ptr + +// for getting cycle for each kind of subface +PE_API double get_cycle(surface_type); } // namespace internal \ No newline at end of file diff --git a/primitive_process/src/base/subface.cpp b/primitive_process/src/base/subface.cpp index 58c7691..1ddfd82 100644 --- a/primitive_process/src/base/subface.cpp +++ b/primitive_process/src/base/subface.cpp @@ -1,4 +1,5 @@ #include +#include "math/math_defs.hpp" namespace internal { @@ -34,4 +35,14 @@ def_export_get_function_ptr_impl(eval_dv_constraint); def_export_get_function_ptr_impl(eval_intersection); #undef def_export_get_function_ptr_impl + +PE_API double get_cycle(surface_type type) +{ + switch (type) { + case surface_type::sphere: return two_pi; + case surface_type::cylinder: return two_pi; + case surface_type::cone: return sqrt_2 * pi; + default: return std::numeric_limits::infinity(); + } +} } // namespace internal \ No newline at end of file diff --git a/shared_module/math/math_defs.hpp b/shared_module/math/math_defs.hpp index 8dec00b..5a87da6 100644 --- a/shared_module/math/math_defs.hpp +++ b/shared_module/math/math_defs.hpp @@ -9,6 +9,8 @@ static constexpr auto two_pi = pi * 2; static constexpr auto pi_div_2 = pi / 2; static constexpr auto inv_pi = 1. / pi; static constexpr auto inv_two_pi = 1. / two_pi; +static constexpr auto sqrt_2 = 1.4142135623730951; +static constexpr auto sqrt_3 = 1.7320508075688772; static const auto x_direction = Eigen::Vector3d{1.0, 0.0, 0.0}; inline void vec3d_conversion(const vector3d& src, Eigen::Ref dst)