Browse Source

use more pointer_wrapper<T> instead of T*;

fix some external bugs;
now parameteric_plane keeps a unique set of chains, at the cost of more complex chain groups
V2-integral
Zhicheng Wang 1 week ago
parent
commit
32d5456806
  1. 4
      blobtree_structure/interface/blobtree.hpp
  2. 18
      blobtree_structure/interface/internal_structs.hpp
  3. 16
      blobtree_structure/src/baked_blobtree.cpp
  4. 12
      blobtree_structure/src/blobtree.cpp
  5. 68
      blobtree_structure/src/internal_structs.cpp
  6. 4
      network_process/interface/process.hpp
  7. 34
      network_process/src/post_topo/map_chains.cpp
  8. 3
      network_process/src/prim_gen/extract_vertex_infos.cpp
  9. 2
      shared_module/utils/hash_ext.hpp
  10. 31
      shared_module/utils/marked_ptr.hpp
  11. 2
      shared_module/utils/pointer_wrapper.hpp

4
blobtree_structure/interface/blobtree.hpp

@ -30,7 +30,7 @@ public:
template <typename T> template <typename T>
struct object_with_index_mapping { struct object_with_index_mapping {
T* object_ptr{nullptr}; pointer_wrapper<T> object_ptr{};
stl_vector_mp<uint32_t> index_mapping{}; stl_vector_mp<uint32_t> index_mapping{};
}; };
@ -56,5 +56,5 @@ public:
size_t get_node_count() const noexcept; size_t get_node_count() const noexcept;
size_t get_primitive_count() const noexcept; size_t get_primitive_count() const noexcept;
internal::node_t& get_node(uint32_t index) noexcept; internal::node_t& get_node(uint32_t index) noexcept;
primitive* get_primitive(uint32_t index) noexcept; pointer_wrapper<primitive> get_primitive(uint32_t index) noexcept;
}; };

18
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 }; enum class eNodeOperation : uint32_t { unionOp = 0, intersectionOp = 1, differenceOp = 2, unsetOp = 3 };
struct runtime_node_t { struct runtime_node_t {
std::variant<eNodeOperation, primitive*> node_data{}; marked_ptr<primitive, 2> node_data{};
runtime_node_t* parent{nullptr}; pointer_wrapper<runtime_node_t> parent{};
runtime_node_t* left_child{nullptr}; pointer_wrapper<runtime_node_t> left_child{};
runtime_node_t* right_child{nullptr}; pointer_wrapper<runtime_node_t> right_child{};
~runtime_node_t() noexcept; ~runtime_node_t() noexcept;
@ -21,12 +21,12 @@ struct runtime_node_t {
bool is_left_child_null() const noexcept; bool is_left_child_null() const noexcept;
bool is_right_child_null() const noexcept; bool is_right_child_null() const noexcept;
bool set_parent(runtime_node_t* parent) noexcept; bool set_parent(pointer_wrapper<runtime_node_t> parent) noexcept;
bool remove_parent(); bool remove_parent();
bool set_left_child(runtime_node_t* child) noexcept; bool set_left_child(pointer_wrapper<runtime_node_t> child) noexcept;
bool set_right_child(runtime_node_t* child) noexcept; bool set_right_child(pointer_wrapper<runtime_node_t> child) noexcept;
bool add_child(runtime_node_t* child) noexcept; bool add_child(pointer_wrapper<runtime_node_t> child) noexcept;
bool remove_child(runtime_node_t* child); bool remove_child(pointer_wrapper<runtime_node_t> child);
}; };
// ====================================================================== // ======================================================================

16
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]; return nodes[index];
} }
primitive* baked_blobtree_t::get_primitive(uint32_t index) noexcept pointer_wrapper<primitive> baked_blobtree_t::get_primitive(uint32_t index) noexcept
{ {
assert(index < primitives.size()); assert(index < primitives.size());
auto& primitive_node = nodes[index]; auto& primitive_node = nodes[index];
@ -24,30 +24,32 @@ primitive* baked_blobtree_t::get_primitive(uint32_t index) noexcept
return primitive_ptr.object_ptr; 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<internal::runtime_node_t> root_node,
size_t& max_index)
{ {
auto& node = baked_tree.nodes[max_index]; auto& node = baked_tree.nodes[max_index];
auto root_index = max_index; auto root_index = max_index;
max_index--; max_index--;
if (root_node->is_primitive_node()) { 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<uint32_t>(primitive_ptr->get_type()); node.type = static_cast<uint32_t>(primitive_ptr->get_type());
node.primitive_index = static_cast<uint32_t>(baked_tree.primitives.size()); node.primitive_index = static_cast<uint32_t>(baked_tree.primitives.size());
baked_tree.leaf_indices.emplace_back(root_index); baked_tree.leaf_indices.emplace_back(root_index);
auto& primitive = baked_tree.primitives.emplace_back(); 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(); auto subfaces = primitive_ptr->get_subfaces();
primitive.index_mapping.reserve(subfaces.size()); primitive.index_mapping.reserve(subfaces.size());
for (size_t i = 0; i < subfaces.size(); ++i) { for (size_t i = 0; i < subfaces.size(); ++i) {
primitive.index_mapping.emplace_back(static_cast<uint32_t>(baked_tree.subfaces.size())); primitive.index_mapping.emplace_back(static_cast<uint32_t>(baked_tree.subfaces.size()));
auto& subface = baked_tree.subfaces.emplace_back(); 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}; subface.index_mapping = {node.primitive_index};
} }
} else { } else {
node.operation = static_cast<uint32_t>(std::get<internal::eNodeOperation>(root_node->node_data)); node.operation = static_cast<uint32_t>(root_node->node_data.get_mark());
if (!root_node->is_right_child_null()) { if (!root_node->is_right_child_null()) {
node.right_child_index = max_index; 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; if (tree.nodes.empty()) return;
// step 1: find root node // step 1: find root node
auto root = &*tree.nodes.begin(); auto root = make_pointer_wrapper(const_cast<internal::runtime_node_t*>(&*tree.nodes.begin()));
while (!root->is_parent_null()) root = root->parent; while (!root->is_parent_null()) root = root->parent;
this->nodes.resize(tree.nodes.size()); this->nodes.resize(tree.nodes.size());

12
blobtree_structure/src/blobtree.cpp

@ -5,7 +5,7 @@ EXTERN_C_BEGIN
blobtree_t::iterator blobtree_t::push_primitive_node(const primitive *primitive_ptr) blobtree_t::iterator blobtree_t::push_primitive_node(const primitive *primitive_ptr)
{ {
auto iter = nodes.emplace(); auto iter = nodes.emplace();
iter->node_data.emplace<primitive *>(const_cast<primitive *>(primitive_ptr)); iter->node_data.set_ptr(const_cast<primitive *>(primitive_ptr));
return iter; return iter;
} }
@ -20,12 +20,12 @@ blobtree_t::iterator blobtree_t::push_operation_node(internal::eNodeOperation op
auto iter = nodes.emplace(); auto iter = nodes.emplace();
iter->node_data.emplace<internal::eNodeOperation>(op); iter->node_data.set_mark(static_cast<size_t>(op));
iter->left_child = &*lhs; iter->left_child = make_pointer_wrapper(*lhs);
iter->right_child = &*rhs; iter->right_child = make_pointer_wrapper(*rhs);
lhs->parent = &*iter; lhs->parent = make_pointer_wrapper(*iter);
rhs->parent = &*iter; rhs->parent = make_pointer_wrapper(*iter);
return iter; return iter;
} }

68
blobtree_structure/src/internal_structs.cpp

@ -8,34 +8,34 @@ namespace internal
runtime_node_t::~runtime_node_t() noexcept runtime_node_t::~runtime_node_t() noexcept
{ {
if (parent) { if (parent) {
if (parent->left_child == this) { if (parent->left_child.raw() == this) {
parent->left_child = nullptr; parent->left_child.clear();
} else if (parent->right_child == this) { } else if (parent->right_child.raw() == this) {
parent->right_child = nullptr; parent->right_child.clear();
} }
} }
if (left_child) { left_child->parent = nullptr; } if (left_child) { left_child->parent.clear(); }
if (right_child) { right_child->parent = nullptr; } if (right_child) { right_child->parent.clear(); }
} }
bool runtime_node_t::is_operation_node() const noexcept { return std::holds_alternative<eNodeOperation>(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_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<runtime_node_t> _parent) noexcept
{ {
if (_parent == nullptr) return false; if (_parent) return false;
if (_parent->is_left_child_null()) if (_parent->is_left_child_null())
_parent->left_child = this; _parent->left_child = make_pointer_wrapper(this);
else if (_parent->is_right_child_null()) else if (_parent->is_right_child_null())
_parent->right_child = this; _parent->right_child = make_pointer_wrapper(this);
else else
return false; return false;
@ -44,45 +44,45 @@ bool runtime_node_t::set_parent(runtime_node_t* _parent) noexcept
bool runtime_node_t::remove_parent() bool runtime_node_t::remove_parent()
{ {
if (parent == nullptr) return false; if (parent) return false;
if (parent->left_child == this) { if (parent->left_child.raw() == this) {
parent->left_child = nullptr; parent->left_child.clear();
} else if (parent->right_child == this) { } else if (parent->right_child.raw() == this) {
parent->right_child = nullptr; parent->right_child.clear();
} else { } else {
throw std::logic_error("Illegal parent which does not have a child pointing to this."); throw std::logic_error("Illegal parent which does not have a child pointing to this.");
} }
parent = nullptr; parent.clear();
return true; return true;
} }
bool runtime_node_t::set_left_child(runtime_node_t* child) noexcept bool runtime_node_t::set_left_child(pointer_wrapper<runtime_node_t> child) noexcept
{ {
if (child == nullptr) return false; if (child) return false;
if (!is_left_child_null() || !child->is_parent_null()) return false; if (!is_left_child_null() || !child->is_parent_null()) return false;
left_child = child; left_child = child;
child->parent = this; child->parent = make_pointer_wrapper(this);
return true; return true;
} }
bool runtime_node_t::set_right_child(runtime_node_t* child) noexcept bool runtime_node_t::set_right_child(pointer_wrapper<runtime_node_t> child) noexcept
{ {
if (child == nullptr) return false; if (child) return false;
if (!is_right_child_null() || !child->is_parent_null()) return false; if (!is_right_child_null() || !child->is_parent_null()) return false;
right_child = child; right_child = child;
child->parent = this; child->parent = make_pointer_wrapper(this);
return true; return true;
} }
bool runtime_node_t::add_child(runtime_node_t* child) noexcept bool runtime_node_t::add_child(pointer_wrapper<runtime_node_t> child) noexcept
{ {
if (child == nullptr) return false; if (child) return false;
if (!child->is_parent_null()) 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 else
return false; return false;
child->parent = this; child->parent = make_pointer_wrapper(this);
return true; return true;
} }
bool runtime_node_t::remove_child(runtime_node_t* child) bool runtime_node_t::remove_child(pointer_wrapper<runtime_node_t> child)
{ {
if (child == nullptr) return false; if (child) return false;
if (left_child == child) { if (left_child == child) {
left_child = nullptr; left_child.clear();
} else if (right_child == child) { } else if (right_child == child) {
right_child = nullptr; right_child.clear();
} else { } else {
throw std::logic_error("Illegal child which does not have a parent pointing to this."); throw std::logic_error("Illegal child which does not have a parent pointing to this.");
} }
child->parent = nullptr; child->parent.clear();
return true; return true;
} }

4
network_process/interface/process.hpp

@ -5,12 +5,14 @@
#include "settings.h" #include "settings.h"
struct parameteric_plane_t { struct parameteric_plane_t {
/// chain associated properties
stl_vector_mp<stl_vector_mp<Eigen::Vector2d>> chain_vertices{}; stl_vector_mp<stl_vector_mp<Eigen::Vector2d>> chain_vertices{};
stl_vector_mp<uint32_t> chain_group_start_indices{};
// iff start/end vertex, then this is signular or not; else this is polar or not // iff start/end vertex, then this is signular or not; else this is polar or not
stl_vector_mp<dynamic_bitset_mp<>> vertex_special_flags{}; stl_vector_mp<dynamic_bitset_mp<>> vertex_special_flags{};
// format: total length is N - 1, and i identifies whether edge [i, i+1) is near parallel or not // format: total length is N - 1, and i identifies whether edge [i, i+1) is near parallel or not
stl_vector_mp<dynamic_bitset_mp<>> edge_near_parallel_flags{}; stl_vector_mp<dynamic_bitset_mp<>> edge_near_parallel_flags{};
/// chain group (by neighboring patch) associated properties
stl_vector_mp<stl_vector_mp<uint16_t>> chain_group_indices{};
}; };
ISNP_API void build_implicit_network_by_blobtree(const s_settings& settings, ISNP_API void build_implicit_network_by_blobtree(const s_settings& settings,

34
network_process/src/post_topo/map_chains.cpp

@ -18,22 +18,32 @@ void map_chain_to_parameteric_plane(const baked_blobtree_t&
} }
const auto& subfaces = tree.subfaces; const auto& subfaces = tree.subfaces;
stl_vector_mp<uint32_t> unique_chain_indices{};
flat_hash_map_mp<uint32_t, uint32_t> old_chain_index_to_unique_index{};
auto unique_end_iter = unique_chain_indices.begin();
for (const auto& [subface_index, patch_indices] : patch_of_subface) { for (const auto& [subface_index, patch_indices] : patch_of_subface) {
const auto& subface = *subfaces[subface_index].object_ptr; const auto& subface = subfaces[subface_index].object_ptr.get();
auto mapping_func = subface.fetch_param_mapping_evaluator(); auto mapping_func = subface.fetch_param_mapping_evaluator();
auto& parameteric_plane = parameteric_planes[subface_index]; auto& parameteric_plane = parameteric_planes[subface_index];
auto& chain_vertices = parameteric_plane.chain_vertices; auto& chain_vertices = parameteric_plane.chain_vertices;
auto& chain_group_start_indices = parameteric_plane.chain_group_start_indices; auto& chain_group_indices = parameteric_plane.chain_group_indices;
auto& chain_vertex_flags = parameteric_plane.vertex_special_flags; auto& chain_vertex_flags = parameteric_plane.vertex_special_flags;
chain_group_start_indices.reserve(patch_indices.size()); chain_group_indices.reserve(patch_indices.size());
chain_group_start_indices.emplace_back(0);
unique_chain_indices.clear();
old_chain_index_to_unique_index.clear();
for (const auto& patch_index : patch_indices) { for (const auto& patch_index : patch_indices) {
const auto& chain_indices = chain_of_patch.at(patch_index); const auto& chain_indices = chain_of_patch.at(patch_index);
chain_group_start_indices.emplace_back(chain_indices.size() + chain_group_start_indices.back()); unique_chain_indices.insert(unique_chain_indices.end(), chain_indices.begin(), chain_indices.end());
chain_vertices.reserve(chain_vertices.size() + chain_indices.size()); }
chain_vertex_flags.reserve(chain_vertex_flags.size() + chain_indices.size()); std::sort(unique_chain_indices.begin(), unique_chain_indices.end());
for (const auto& chain_index : chain_indices) { 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]; const auto& chain = chains[chain_index];
auto& chain_vertices_ = chain_vertices.emplace_back(); auto& chain_vertices_ = chain_vertices.emplace_back();
@ -48,6 +58,14 @@ void map_chain_to_parameteric_plane(const baked_blobtree_t&
chain_vertex_flags_[0] = chain_end_vertex_signular_flag[2 * chain_index]; 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]; 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]; });
} }
} }
} }

3
network_process/src/prim_gen/extract_vertex_infos.cpp

@ -6,8 +6,7 @@ aabb_t mark_primitive_boundings(double aabb_margin, const baked_blobtree_t& tree
aabb_t scene_aabb{}; aabb_t scene_aabb{};
for (const auto [primitive_ptr, _] : tree.primitives) { for (const auto [primitive_ptr, _] : tree.primitives) {
const auto& primitive = *primitive_ptr; aabb_t primitive_aabb = primitive_ptr->fetch_aabb();
aabb_t primitive_aabb = primitive.fetch_aabb();
primitive_aabb.min().array() -= aabb_margin; primitive_aabb.min().array() -= aabb_margin;
primitive_aabb.max().array() += aabb_margin; primitive_aabb.max().array() += aabb_margin;
scene_aabb.extend(primitive_aabb); scene_aabb.extend(primitive_aabb);

2
shared_module/utils/hash_ext.hpp

@ -44,7 +44,7 @@ struct hash_funcs_fn
else if constexpr (std::is_floating_point_v<T>) else if constexpr (std::is_floating_point_v<T>)
{ {
using integral_type = typename detail::float_to_int_type<T>::type; using integral_type = typename detail::float_to_int_type<T>::type;
Eigen::Matrix<integral_type, N, N + 1> int_mat = (trans.array() / static_cast<T>(detail::float_hash_epsilon)).template cast<integral_type>(); Eigen::Matrix<integral_type, N, N + 1> int_mat = (trans.matrix().array() / static_cast<T>(detail::float_hash_epsilon)).template cast<integral_type>();
return XXH3_64bits(int_mat.data(), sizeof(integral_type) * N * (N + 1)); return XXH3_64bits(int_mat.data(), sizeof(integral_type) * N * (N + 1));
} }
else else

31
shared_module/utils/marked_ptr.hpp

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <cstddef> #include <cstddef>
template <typename T, size_t bits_to_store> template <typename T, size_t bits_to_store>
struct marked_ptr { struct marked_ptr {
static constexpr size_t mask = (1 << bits_to_store) - 1; static constexpr size_t mask = (1 << bits_to_store) - 1;
@ -26,31 +27,31 @@ protected:
T* ptr{nullptr}; T* ptr{nullptr};
}; };
template <typename T> // template <typename T>
struct marked_ptr<T, 1> { // struct marked_ptr<T, 1> {
// static_assert(alignof(T) >= 1); // // 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: // protected:
T* ptr{nullptr}; // T* ptr{nullptr};
}; // };
template <typename F, typename T, size_t bits_to_store> template <typename F, typename T, size_t bits_to_store>
inline static marked_ptr<F, bits_to_store> static_pointer_cast(const marked_ptr<T, bits_to_store>& p) inline static marked_ptr<F, bits_to_store> static_pointer_cast(const marked_ptr<T, bits_to_store>& p)

2
shared_module/utils/pointer_wrapper.hpp

@ -23,6 +23,8 @@ struct pointer_wrapper{
auto raw() const noexcept -> T* { return ptr; } auto raw() const noexcept -> T* { return ptr; }
operator bool() const noexcept { return ptr != nullptr; } operator bool() const noexcept { return ptr != nullptr; }
void clear() noexcept { ptr = nullptr; }
private: private:
T* ptr{nullptr}; T* ptr{nullptr};
}; };

Loading…
Cancel
Save