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. 10
      blobtree_structure/interface/blobtree.hpp
  2. 30
      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. 68
      network_process/src/post_topo/map_chains.cpp
  8. 7
      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

10
blobtree_structure/interface/blobtree.hpp

@ -30,7 +30,7 @@ public:
template <typename T>
struct object_with_index_mapping {
T* object_ptr{nullptr};
pointer_wrapper<T> object_ptr{};
stl_vector_mp<uint32_t> 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<primitive> get_primitive(uint32_t index) noexcept;
};

30
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<eNodeOperation, primitive*> node_data{};
marked_ptr<primitive, 2> node_data{};
runtime_node_t* parent{nullptr};
runtime_node_t* left_child{nullptr};
runtime_node_t* right_child{nullptr};
pointer_wrapper<runtime_node_t> parent{};
pointer_wrapper<runtime_node_t> left_child{};
pointer_wrapper<runtime_node_t> 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<runtime_node_t> 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<runtime_node_t> child) noexcept;
bool set_right_child(pointer_wrapper<runtime_node_t> child) noexcept;
bool add_child(pointer_wrapper<runtime_node_t> child) noexcept;
bool remove_child(pointer_wrapper<runtime_node_t> 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

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];
}
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());
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<internal::runtime_node_t> 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<uint32_t>(primitive_ptr->get_type());
node.primitive_index = static_cast<uint32_t>(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<uint32_t>(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<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()) {
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<internal::runtime_node_t*>(&*tree.nodes.begin()));
while (!root->is_parent_null()) root = root->parent;
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)
{
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;
}
@ -20,12 +20,12 @@ blobtree_t::iterator blobtree_t::push_operation_node(internal::eNodeOperation op
auto iter = nodes.emplace();
iter->node_data.emplace<internal::eNodeOperation>(op);
iter->left_child = &*lhs;
iter->right_child = &*rhs;
iter->node_data.set_mark(static_cast<size_t>(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;
}

68
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<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_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())
_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<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;
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<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;
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<runtime_node_t> 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<runtime_node_t> 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;
}

4
network_process/interface/process.hpp

@ -5,12 +5,14 @@
#include "settings.h"
struct parameteric_plane_t {
/// chain associated properties
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
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
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,

68
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<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) {
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]; });
}
}
}

7
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));
}

2
shared_module/utils/hash_ext.hpp

@ -44,7 +44,7 @@ struct hash_funcs_fn
else if constexpr (std::is_floating_point_v<T>)
{
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));
}
else

31
shared_module/utils/marked_ptr.hpp

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

2
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};
};

Loading…
Cancel
Save