diff --git a/blobtree_structure/interface/blobtree.hpp b/blobtree_structure/interface/blobtree.hpp index 25c07f0..ae921b4 100644 --- a/blobtree_structure/interface/blobtree.hpp +++ b/blobtree_structure/interface/blobtree.hpp @@ -30,7 +30,7 @@ public: template struct object_with_index_mapping { - T* object_ptr{nullptr}; + pointer_wrapper object_ptr{}; stl_vector_mp index_mapping{}; }; @@ -53,8 +53,8 @@ public: baked_blobtree_t(const blobtree_t&) noexcept; - size_t get_node_count() const noexcept; - size_t get_primitive_count() const noexcept; - internal::node_t& get_node(uint32_t index) noexcept; - primitive* get_primitive(uint32_t index) noexcept; + size_t get_node_count() const noexcept; + size_t get_primitive_count() const noexcept; + internal::node_t& get_node(uint32_t index) noexcept; + pointer_wrapper get_primitive(uint32_t index) noexcept; }; \ No newline at end of file diff --git a/blobtree_structure/interface/internal_structs.hpp b/blobtree_structure/interface/internal_structs.hpp index 9eede7c..c84e115 100644 --- a/blobtree_structure/interface/internal_structs.hpp +++ b/blobtree_structure/interface/internal_structs.hpp @@ -7,11 +7,11 @@ namespace internal enum class eNodeOperation : uint32_t { unionOp = 0, intersectionOp = 1, differenceOp = 2, unsetOp = 3 }; struct runtime_node_t { - std::variant node_data{}; + marked_ptr node_data{}; - runtime_node_t* parent{nullptr}; - runtime_node_t* left_child{nullptr}; - runtime_node_t* right_child{nullptr}; + pointer_wrapper parent{}; + pointer_wrapper left_child{}; + pointer_wrapper right_child{}; ~runtime_node_t() noexcept; @@ -21,12 +21,12 @@ struct runtime_node_t { bool is_left_child_null() const noexcept; bool is_right_child_null() const noexcept; - bool set_parent(runtime_node_t* parent) noexcept; + bool set_parent(pointer_wrapper parent) noexcept; bool remove_parent(); - bool set_left_child(runtime_node_t* child) noexcept; - bool set_right_child(runtime_node_t* child) noexcept; - bool add_child(runtime_node_t* child) noexcept; - bool remove_child(runtime_node_t* child); + bool set_left_child(pointer_wrapper child) noexcept; + bool set_right_child(pointer_wrapper child) noexcept; + bool add_child(pointer_wrapper child) noexcept; + bool remove_child(pointer_wrapper child); }; // ====================================================================== @@ -44,11 +44,11 @@ struct BS_API node_t { node_t() noexcept; eNodeOperation get_operation() const noexcept; - void set_operation(eNodeOperation op) noexcept; - bool is_primitive_node() const noexcept; - bool is_operation_node() const noexcept; - bool is_parent_null() const noexcept; - bool is_left_child_null() const noexcept; - bool is_right_child_null() const noexcept; + void set_operation(eNodeOperation op) noexcept; + bool is_primitive_node() const noexcept; + bool is_operation_node() const noexcept; + bool is_parent_null() const noexcept; + bool is_left_child_null() const noexcept; + bool is_right_child_null() const noexcept; }; } // namespace internal \ No newline at end of file diff --git a/blobtree_structure/src/baked_blobtree.cpp b/blobtree_structure/src/baked_blobtree.cpp index a824ce6..d3a4b5d 100644 --- a/blobtree_structure/src/baked_blobtree.cpp +++ b/blobtree_structure/src/baked_blobtree.cpp @@ -15,7 +15,7 @@ internal::node_t& baked_blobtree_t::get_node(uint32_t index) noexcept return nodes[index]; } -primitive* baked_blobtree_t::get_primitive(uint32_t index) noexcept +pointer_wrapper baked_blobtree_t::get_primitive(uint32_t index) noexcept { assert(index < primitives.size()); auto& primitive_node = nodes[index]; @@ -24,30 +24,32 @@ primitive* baked_blobtree_t::get_primitive(uint32_t index) noexcept return primitive_ptr.object_ptr; } -void recursive_bake_blobtree(baked_blobtree_t& baked_tree, const internal::runtime_node_t* root_node, size_t& max_index) +void recursive_bake_blobtree(baked_blobtree_t& baked_tree, + const pointer_wrapper root_node, + size_t& max_index) { auto& node = baked_tree.nodes[max_index]; auto root_index = max_index; max_index--; if (root_node->is_primitive_node()) { - auto primitive_ptr = std::get<1>(root_node->node_data); + auto primitive_ptr = root_node->node_data.get_ptr(); node.type = static_cast(primitive_ptr->get_type()); node.primitive_index = static_cast(baked_tree.primitives.size()); baked_tree.leaf_indices.emplace_back(root_index); auto& primitive = baked_tree.primitives.emplace_back(); - primitive.object_ptr = primitive_ptr; + primitive.object_ptr = make_pointer_wrapper(primitive_ptr); auto subfaces = primitive_ptr->get_subfaces(); primitive.index_mapping.reserve(subfaces.size()); for (size_t i = 0; i < subfaces.size(); ++i) { primitive.index_mapping.emplace_back(static_cast(baked_tree.subfaces.size())); auto& subface = baked_tree.subfaces.emplace_back(); - subface.object_ptr = subfaces[i].get_ptr(); + subface.object_ptr = make_pointer_wrapper(subfaces[i].get_ptr()); subface.index_mapping = {node.primitive_index}; } } else { - node.operation = static_cast(std::get(root_node->node_data)); + node.operation = static_cast(root_node->node_data.get_mark()); if (!root_node->is_right_child_null()) { node.right_child_index = max_index; @@ -70,7 +72,7 @@ baked_blobtree_t::baked_blobtree_t(const blobtree_t& tree) noexcept if (tree.nodes.empty()) return; // step 1: find root node - auto root = &*tree.nodes.begin(); + auto root = make_pointer_wrapper(const_cast(&*tree.nodes.begin())); while (!root->is_parent_null()) root = root->parent; this->nodes.resize(tree.nodes.size()); diff --git a/blobtree_structure/src/blobtree.cpp b/blobtree_structure/src/blobtree.cpp index e2fd293..7128a56 100644 --- a/blobtree_structure/src/blobtree.cpp +++ b/blobtree_structure/src/blobtree.cpp @@ -5,7 +5,7 @@ EXTERN_C_BEGIN blobtree_t::iterator blobtree_t::push_primitive_node(const primitive *primitive_ptr) { auto iter = nodes.emplace(); - iter->node_data.emplace(const_cast(primitive_ptr)); + iter->node_data.set_ptr(const_cast(primitive_ptr)); return iter; } @@ -20,12 +20,12 @@ blobtree_t::iterator blobtree_t::push_operation_node(internal::eNodeOperation op auto iter = nodes.emplace(); - iter->node_data.emplace(op); - iter->left_child = &*lhs; - iter->right_child = &*rhs; + iter->node_data.set_mark(static_cast(op)); + iter->left_child = make_pointer_wrapper(*lhs); + iter->right_child = make_pointer_wrapper(*rhs); - lhs->parent = &*iter; - rhs->parent = &*iter; + lhs->parent = make_pointer_wrapper(*iter); + rhs->parent = make_pointer_wrapper(*iter); return iter; } diff --git a/blobtree_structure/src/internal_structs.cpp b/blobtree_structure/src/internal_structs.cpp index 3d56d18..d91e39e 100644 --- a/blobtree_structure/src/internal_structs.cpp +++ b/blobtree_structure/src/internal_structs.cpp @@ -8,34 +8,34 @@ namespace internal runtime_node_t::~runtime_node_t() noexcept { if (parent) { - if (parent->left_child == this) { - parent->left_child = nullptr; - } else if (parent->right_child == this) { - parent->right_child = nullptr; + if (parent->left_child.raw() == this) { + parent->left_child.clear(); + } else if (parent->right_child.raw() == this) { + parent->right_child.clear(); } } - if (left_child) { left_child->parent = nullptr; } - if (right_child) { right_child->parent = nullptr; } + if (left_child) { left_child->parent.clear(); } + if (right_child) { right_child->parent.clear(); } } -bool runtime_node_t::is_operation_node() const noexcept { return std::holds_alternative(node_data); } +bool runtime_node_t::is_operation_node() const noexcept { return node_data.get_ptr() == nullptr; } bool runtime_node_t::is_primitive_node() const noexcept { return !is_operation_node(); } -bool runtime_node_t::is_parent_null() const noexcept { return parent == nullptr; } +bool runtime_node_t::is_parent_null() const noexcept { return parent; } -bool runtime_node_t::is_left_child_null() const noexcept { return left_child == nullptr; } +bool runtime_node_t::is_left_child_null() const noexcept { return left_child; } -bool runtime_node_t::is_right_child_null() const noexcept { return right_child == nullptr; } +bool runtime_node_t::is_right_child_null() const noexcept { return right_child; } -bool runtime_node_t::set_parent(runtime_node_t* _parent) noexcept +bool runtime_node_t::set_parent(pointer_wrapper _parent) noexcept { - if (_parent == nullptr) return false; + if (_parent) return false; if (_parent->is_left_child_null()) - _parent->left_child = this; + _parent->left_child = make_pointer_wrapper(this); else if (_parent->is_right_child_null()) - _parent->right_child = this; + _parent->right_child = make_pointer_wrapper(this); else return false; @@ -44,45 +44,45 @@ bool runtime_node_t::set_parent(runtime_node_t* _parent) noexcept bool runtime_node_t::remove_parent() { - if (parent == nullptr) return false; + if (parent) return false; - if (parent->left_child == this) { - parent->left_child = nullptr; - } else if (parent->right_child == this) { - parent->right_child = nullptr; + if (parent->left_child.raw() == this) { + parent->left_child.clear(); + } else if (parent->right_child.raw() == this) { + parent->right_child.clear(); } else { throw std::logic_error("Illegal parent which does not have a child pointing to this."); } - parent = nullptr; + parent.clear(); return true; } -bool runtime_node_t::set_left_child(runtime_node_t* child) noexcept +bool runtime_node_t::set_left_child(pointer_wrapper child) noexcept { - if (child == nullptr) return false; + if (child) return false; if (!is_left_child_null() || !child->is_parent_null()) return false; left_child = child; - child->parent = this; + child->parent = make_pointer_wrapper(this); return true; } -bool runtime_node_t::set_right_child(runtime_node_t* child) noexcept +bool runtime_node_t::set_right_child(pointer_wrapper child) noexcept { - if (child == nullptr) return false; + if (child) return false; if (!is_right_child_null() || !child->is_parent_null()) return false; right_child = child; - child->parent = this; + child->parent = make_pointer_wrapper(this); return true; } -bool runtime_node_t::add_child(runtime_node_t* child) noexcept +bool runtime_node_t::add_child(pointer_wrapper child) noexcept { - if (child == nullptr) return false; + if (child) return false; if (!child->is_parent_null()) return false; @@ -93,23 +93,23 @@ bool runtime_node_t::add_child(runtime_node_t* child) noexcept else return false; - child->parent = this; + child->parent = make_pointer_wrapper(this); return true; } -bool runtime_node_t::remove_child(runtime_node_t* child) +bool runtime_node_t::remove_child(pointer_wrapper child) { - if (child == nullptr) return false; + if (child) return false; if (left_child == child) { - left_child = nullptr; + left_child.clear(); } else if (right_child == child) { - right_child = nullptr; + right_child.clear(); } else { throw std::logic_error("Illegal child which does not have a parent pointing to this."); } - child->parent = nullptr; + child->parent.clear(); return true; } diff --git a/network_process/interface/process.hpp b/network_process/interface/process.hpp index 1ca8fab..6907658 100644 --- a/network_process/interface/process.hpp +++ b/network_process/interface/process.hpp @@ -5,12 +5,14 @@ #include "settings.h" struct parameteric_plane_t { + /// chain associated properties stl_vector_mp> chain_vertices{}; - stl_vector_mp chain_group_start_indices{}; // iff start/end vertex, then this is signular or not; else this is polar or not stl_vector_mp> vertex_special_flags{}; // format: total length is N - 1, and i identifies whether edge [i, i+1) is near parallel or not stl_vector_mp> edge_near_parallel_flags{}; + /// chain group (by neighboring patch) associated properties + stl_vector_mp> chain_group_indices{}; }; ISNP_API void build_implicit_network_by_blobtree(const s_settings& settings, diff --git a/network_process/src/post_topo/map_chains.cpp b/network_process/src/post_topo/map_chains.cpp index d2c6680..87d4aec 100644 --- a/network_process/src/post_topo/map_chains.cpp +++ b/network_process/src/post_topo/map_chains.cpp @@ -17,37 +17,55 @@ void map_chain_to_parameteric_plane(const baked_blobtree_t& patch_of_subface[subface_index].emplace_back(patch_index); } - const auto& subfaces = tree.subfaces; + const auto& subfaces = tree.subfaces; + stl_vector_mp unique_chain_indices{}; + flat_hash_map_mp old_chain_index_to_unique_index{}; + auto unique_end_iter = unique_chain_indices.begin(); for (const auto& [subface_index, patch_indices] : patch_of_subface) { - const auto& subface = *subfaces[subface_index].object_ptr; - auto mapping_func = subface.fetch_param_mapping_evaluator(); - auto& parameteric_plane = parameteric_planes[subface_index]; - auto& chain_vertices = parameteric_plane.chain_vertices; - auto& chain_group_start_indices = parameteric_plane.chain_group_start_indices; - auto& chain_vertex_flags = parameteric_plane.vertex_special_flags; - chain_group_start_indices.reserve(patch_indices.size()); - chain_group_start_indices.emplace_back(0); + const auto& subface = subfaces[subface_index].object_ptr.get(); + auto mapping_func = subface.fetch_param_mapping_evaluator(); + auto& parameteric_plane = parameteric_planes[subface_index]; + auto& chain_vertices = parameteric_plane.chain_vertices; + auto& chain_group_indices = parameteric_plane.chain_group_indices; + auto& chain_vertex_flags = parameteric_plane.vertex_special_flags; + chain_group_indices.reserve(patch_indices.size()); + unique_chain_indices.clear(); + old_chain_index_to_unique_index.clear(); for (const auto& patch_index : patch_indices) { const auto& chain_indices = chain_of_patch.at(patch_index); - chain_group_start_indices.emplace_back(chain_indices.size() + chain_group_start_indices.back()); - chain_vertices.reserve(chain_vertices.size() + chain_indices.size()); - chain_vertex_flags.reserve(chain_vertex_flags.size() + chain_indices.size()); - for (const auto& chain_index : chain_indices) { - const auto& chain = chains[chain_index]; + 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); + + chain_vertices.reserve(unique_chain_indices.size()); + chain_vertex_flags.reserve(unique_chain_indices.size()); + for (const auto& chain_index : unique_chain_indices) { + const auto& chain = chains[chain_index]; + + auto& chain_vertices_ = chain_vertices.emplace_back(); + chain_vertices_.resize(chain.size()); + std::transform(chain.begin(), chain.end(), chain_vertices_.begin(), [&](uint32_t vertex_index) { + auto mapped_vertex_index = vertex_old_index_to_unique_index.at(vertex_index); + return mapping_func(vertices[mapped_vertex_index]); + }); - auto& chain_vertices_ = chain_vertices.emplace_back(); - chain_vertices_.resize(chain.size()); - std::transform(chain.begin(), chain.end(), chain_vertices_.begin(), [&](uint32_t vertex_index) { - auto mapped_vertex_index = vertex_old_index_to_unique_index.at(vertex_index); - return mapping_func(vertices[mapped_vertex_index]); - }); + auto& chain_vertex_flags_ = chain_vertex_flags.emplace_back(); + chain_vertex_flags_.resize(chain.size()); + chain_vertex_flags_[0] = chain_end_vertex_signular_flag[2 * chain_index]; + chain_vertex_flags_[chain.size() - 1] = chain_end_vertex_signular_flag[2 * chain_index + 1]; + } - auto& chain_vertex_flags_ = chain_vertex_flags.emplace_back(); - chain_vertex_flags_.resize(chain.size()); - chain_vertex_flags_[0] = chain_end_vertex_signular_flag[2 * chain_index]; - chain_vertex_flags_[chain.size() - 1] = chain_end_vertex_signular_flag[2 * chain_index + 1]; - } + 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(); + std::transform(chain_indices.begin(), + chain_indices.end(), + std::back_inserter(chain_group), + [&](uint32_t chain_index) { return old_chain_index_to_unique_index[chain_index]; }); } } } \ No newline at end of file diff --git a/network_process/src/prim_gen/extract_vertex_infos.cpp b/network_process/src/prim_gen/extract_vertex_infos.cpp index 6186fb0..8cd83c4 100644 --- a/network_process/src/prim_gen/extract_vertex_infos.cpp +++ b/network_process/src/prim_gen/extract_vertex_infos.cpp @@ -6,10 +6,9 @@ aabb_t mark_primitive_boundings(double aabb_margin, const baked_blobtree_t& tree aabb_t scene_aabb{}; for (const auto [primitive_ptr, _] : tree.primitives) { - const auto& primitive = *primitive_ptr; - aabb_t primitive_aabb = primitive.fetch_aabb(); - primitive_aabb.min().array() -= aabb_margin; - primitive_aabb.max().array() += aabb_margin; + aabb_t primitive_aabb = primitive_ptr->fetch_aabb(); + primitive_aabb.min().array() -= aabb_margin; + primitive_aabb.max().array() += aabb_margin; scene_aabb.extend(primitive_aabb); primitive_boundings.emplace_back(std::move(primitive_aabb)); } diff --git a/shared_module/utils/hash_ext.hpp b/shared_module/utils/hash_ext.hpp index 1105723..2f12b65 100644 --- a/shared_module/utils/hash_ext.hpp +++ b/shared_module/utils/hash_ext.hpp @@ -44,7 +44,7 @@ struct hash_funcs_fn else if constexpr (std::is_floating_point_v) { using integral_type = typename detail::float_to_int_type::type; - Eigen::Matrix int_mat = (trans.array() / static_cast(detail::float_hash_epsilon)).template cast(); + Eigen::Matrix int_mat = (trans.matrix().array() / static_cast(detail::float_hash_epsilon)).template cast(); return XXH3_64bits(int_mat.data(), sizeof(integral_type) * N * (N + 1)); } else diff --git a/shared_module/utils/marked_ptr.hpp b/shared_module/utils/marked_ptr.hpp index 9d119ee..9cce99a 100644 --- a/shared_module/utils/marked_ptr.hpp +++ b/shared_module/utils/marked_ptr.hpp @@ -1,6 +1,7 @@ #pragma once #include + template struct marked_ptr { static constexpr size_t mask = (1 << bits_to_store) - 1; @@ -26,31 +27,31 @@ protected: T* ptr{nullptr}; }; -template -struct marked_ptr { - // static_assert(alignof(T) >= 1); +// template +// struct marked_ptr { +// // static_assert(alignof(T) >= 1); - marked_ptr(T* ptr = nullptr) : ptr(ptr) {} +// marked_ptr(T* ptr = nullptr) : ptr(ptr) {} - marked_ptr(T* ptr, bool mark) : ptr((T*)((size_t)ptr | mark)) {} +// marked_ptr(T* ptr, bool mark) : ptr((T*)((size_t)ptr | mark)) {} - T* get_ptr() const { return (T*)((size_t)ptr & ~1); } +// T* get_ptr() const { return (T*)((size_t)ptr & ~1); } - bool is_marked() const { return (size_t)ptr & 1; } +// bool is_marked() const { return (size_t)ptr & 1; } - void set_ptr(T* ptr) { this->ptr = (T*)((size_t)ptr | is_marked()); } +// void set_ptr(T* ptr) { this->ptr = (T*)((size_t)ptr | is_marked()); } - void set_mark(bool mark) { ptr = (T*)((size_t)ptr | mark); } +// void set_mark(bool mark) { ptr = (T*)((size_t)ptr | mark); } - operator T*() const { return get_ptr(); } +// operator T*() const { return get_ptr(); } - operator bool() const { return is_marked(); } +// operator bool() const { return is_marked(); } - T* operator->() const { return get_ptr(); } +// T* operator->() const { return get_ptr(); } -protected: - T* ptr{nullptr}; -}; +// protected: +// T* ptr{nullptr}; +// }; template inline static marked_ptr static_pointer_cast(const marked_ptr& p) diff --git a/shared_module/utils/pointer_wrapper.hpp b/shared_module/utils/pointer_wrapper.hpp index f91735c..c82035c 100644 --- a/shared_module/utils/pointer_wrapper.hpp +++ b/shared_module/utils/pointer_wrapper.hpp @@ -23,6 +23,8 @@ struct pointer_wrapper{ auto raw() const noexcept -> T* { return ptr; } operator bool() const noexcept { return ptr != nullptr; } + void clear() noexcept { ptr = nullptr; } + private: T* ptr{nullptr}; };