diff --git a/blobtree_structure/src/baked_blobtree.cpp b/blobtree_structure/src/baked_blobtree.cpp index 911863a..a824ce6 100644 --- a/blobtree_structure/src/baked_blobtree.cpp +++ b/blobtree_structure/src/baked_blobtree.cpp @@ -38,13 +38,12 @@ void recursive_bake_blobtree(baked_blobtree_t& baked_tree, const internal::runti baked_tree.leaf_indices.emplace_back(root_index); auto& primitive = baked_tree.primitives.emplace_back(); primitive.object_ptr = primitive_ptr; - auto subface_count = primitive_ptr->get_subface_count(); - auto subfaces_ptr = primitive_ptr->get_subface(); - primitive.index_mapping.reserve(subface_count); - for (size_t i = 0; i < subface_count; ++i) { + 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_ptr[i].get_ptr(); + subface.object_ptr = subfaces[i].get_ptr(); subface.index_mapping = {node.primitive_index}; } } else { diff --git a/network_process/src/prim_gen/extract_vertex_infos.cpp b/network_process/src/prim_gen/extract_vertex_infos.cpp index c39ab4d..6186fb0 100644 --- a/network_process/src/prim_gen/extract_vertex_infos.cpp +++ b/network_process/src/prim_gen/extract_vertex_infos.cpp @@ -1,8 +1,5 @@ #include -using aabb_t = Eigen::AlignedBox; -const aabb_t aabb_unit = aabb_t(Eigen::Vector3d(-1, -1, -1), Eigen::Vector3d(1, 1, 1)); - aabb_t mark_primitive_boundings(double aabb_margin, const baked_blobtree_t& tree, stl_vector_mp& primitive_boundings) { primitive_boundings.reserve(tree.primitives.size()); diff --git a/primitive_process/interface/base/primitive.hpp b/primitive_process/interface/base/primitive.hpp index 4ef18d2..a5ab2ac 100644 --- a/primitive_process/interface/base/primitive.hpp +++ b/primitive_process/interface/base/primitive.hpp @@ -13,6 +13,7 @@ template using marked_subface_ptr_t = marked_ptr; using aabb_t = Eigen::AlignedBox; +const aabb_t k_aabb_unit = aabb_t(Eigen::Vector3d(-1, -1, -1), Eigen::Vector3d(1, 1, 1)); enum class sign_t : uint8_t { positive = 1, negative = 2, zero = 0 }; @@ -50,21 +51,20 @@ EXTERN_C struct PE_API primitive { virtual void initialize(primitive_data_center_t &) = 0; virtual void destroy() = 0; - virtual primitive_type get_type() const = 0; - virtual marked_subface_ptr_t *get_subface() const = 0; - virtual size_t get_subface_count() const = 0; - aabb_t m_aabb = aabb_t(Eigen::Vector3d(-1, -1, -1), Eigen::Vector3d(1, 1, 1)); + virtual primitive_type get_type() const = 0; + virtual stl_vector_mp> get_subfaces() const = 0; + virtual stl_vector_mp get_subface_types() const = 0; // sign_t judge_sign_by_subface_sdf(const std::vector &) const; // sign_t judge_sign_by_subface_sdf_sign(const std::vector &) const; dynamic_bitset_mp<> judge_sign_by_subface_sign(stl_vector_mp>) const; - - aabb_t fetch_aabb() const; + aabb_t fetch_aabb() const { return m_aabb; } void apply_transform(internal::transform_type, Eigen::Vector4d); protected: - virtual void initialize(primitive_data_center_t &, - const std::vector> &) = 0; + void initialize(primitive_data_center_t &, const stl_vector_mp &); + + aabb_t m_aabb{k_aabb_unit}; }; \ No newline at end of file diff --git a/primitive_process/interface/base/subface.hpp b/primitive_process/interface/base/subface.hpp index 886e8e8..4eb3df4 100644 --- a/primitive_process/interface/base/subface.hpp +++ b/primitive_process/interface/base/subface.hpp @@ -67,8 +67,8 @@ EXTERN_C struct PE_API subface { virtual std::function fetch_solver_evaluator() const = 0; - primitive_data_center_t *data_center{nullptr}; - internal::paired_model_matrix *model_matrices{nullptr}; + primitive_data_center_ptr_t data_center{}; + internal::paired_model_matrix_ptr_t model_matrices{}; internal::transform_block &raw_local_to_world() const; internal::transform_block &raw_world_to_local() const; @@ -86,5 +86,7 @@ protected: // NOTE: to avoid any specialization, always keep the characteristic part in the first row/column, which should be impled by // subface's presentation // return: [ptr to changed paired_model_matrix, is_reversed] - std::pair apply_transform(internal::transform_type, Eigen::Vector4d); + // MODIFY: only plane will change the sign of its subface, so we do not need to return the changed sign here + // std::pair apply_transform(internal::transform_type, Eigen::Vector4d); + internal::paired_model_matrix_ptr_t apply_transform(internal::transform_type, Eigen::Vector4d); }; \ No newline at end of file diff --git a/primitive_process/interface/data/data_center.hpp b/primitive_process/interface/data/data_center.hpp index ac3855c..c20e5e5 100644 --- a/primitive_process/interface/data/data_center.hpp +++ b/primitive_process/interface/data/data_center.hpp @@ -5,15 +5,28 @@ #include "primitive/simple/sphere.hpp" #include "primitive/simple/cylinder.hpp" +template +using surface_container_t = tagged_hashed_refcount_hive_mp; + +using plane_container_t = surface_container_t; +using sphere_container_t = surface_container_t; +using cylinder_container_t = surface_container_t; + EXTERN_C struct PE_API primitive_data_center_t { primitive_data_center_t() noexcept; ~primitive_data_center_t() noexcept; - hashed_refcount_hive_mp transform_blocks{}; + hashed_refcount_hive_mp transform_blocks{}; // all other data depend on cached transform_blocks - hashed_refcount_hive_mp planes{}; - hashed_refcount_hive_mp spheres{}; - hashed_refcount_hive_mp cylinders{}; + using surface_containers = std::variant; + std::array(surface_type::max_count)> surfaces{}; + + auto require_transform_block(const internal::paired_model_matrix& matrix) -> internal::paired_model_matrix_ptr_t; + void require_surface(surface_type type, + const internal::paired_model_matrix_ptr_t& matrix, + marked_subface_ptr_t& subface); + void release_transform_block(const internal::paired_model_matrix& matrix); + void release_surface(surface_type type, const marked_subface_ptr_t& subface); }; namespace internal diff --git a/primitive_process/interface/data/data_type.hpp b/primitive_process/interface/data/data_type.hpp index 7348ad2..c30099e 100644 --- a/primitive_process/interface/data/data_type.hpp +++ b/primitive_process/interface/data/data_type.hpp @@ -1,9 +1,9 @@ #pragma once -#include - #include #include +#include +#include namespace internal { @@ -16,6 +16,8 @@ struct paired_model_matrix { transform_block world_to_local{internal::transform_block::Identity()}; }; +using paired_model_matrix_ptr_t = pointer_wrapper; + const paired_model_matrix identity_model_matrix{internal::transform_block::Identity(), internal::transform_block::Identity()}; const auto plane_to_z_pos_1_model_matrix = []() { paired_model_matrix res{}; @@ -28,7 +30,7 @@ const auto plane_to_z_pos_1_model_matrix = []() { res.local_to_world.translation() = Eigen::Vector3d{0, 0, 1}; return res; }(); -const auto plane_to_z_model_matrix = []() { +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}; @@ -56,22 +58,30 @@ enum class transform_type : uint8_t { scale, rotation, translation }; } // namespace internal struct primitive_data_center_t; +using primitive_data_center_ptr_t = pointer_wrapper; + +enum class surface_type : uint8_t { plane, sphere, cylinder, cone, max_count }; namespace detail { template <> struct hasher { - size_t operator()(const internal::transform_block& block) const - { - return XXH3_64bits(block.data(), sizeof(internal::transform_block)); - } + size_t operator()(const internal::transform_block& block) const { return hash_funcs(block); } }; template <> struct hasher { size_t operator()(const internal::paired_model_matrix& paired_matrix) const { - return XXH3_64bits(paired_matrix.local_to_world.data(), sizeof(internal::paired_model_matrix)); + return hash_funcs(paired_matrix.local_to_world); + } +}; + +template +struct tagged_hasher { + size_t operator()(const internal::paired_model_matrix& paired_matrix) const + { + return hash_funcs(paired_matrix.local_to_world); } }; diff --git a/primitive_process/interface/primitive/simple/cylinder.hpp b/primitive_process/interface/primitive/simple/cylinder.hpp index 0f42e37..aeb87d8 100644 --- a/primitive_process/interface/primitive/simple/cylinder.hpp +++ b/primitive_process/interface/primitive/simple/cylinder.hpp @@ -6,21 +6,26 @@ namespace internal { -struct cylinder_t final : primitive { +struct cylinder_t final : public primitive { void initialize(primitive_data_center_t &) override; void destroy() override; primitive_type get_type() const override { return PRIMITIVE_TYPE_CYLINDER; }; + stl_vector_mp> get_subfaces() const override + { + return {static_pointer_cast(cylinder_face), + static_pointer_cast(bottom_plane), + static_pointer_cast(top_plane)}; + } + + stl_vector_mp get_subface_types() const override + { + return {surface_type::cylinder, surface_type::plane, surface_type::plane}; + } + marked_subface_ptr_t cylinder_face{}; marked_subface_ptr_t bottom_plane{}; marked_subface_ptr_t top_plane{}; - -protected: - void initialize(primitive_data_center_t &, const std::vector> &) override; - - marked_subface_ptr_t *get_subface() const override { return (marked_subface_ptr_t *)(&cylinder_face); } - - size_t get_subface_count() const override { return 3; } }; } // namespace internal \ No newline at end of file diff --git a/primitive_process/interface/primitive/simple/sphere.hpp b/primitive_process/interface/primitive/simple/sphere.hpp index 52dca16..d508d01 100644 --- a/primitive_process/interface/primitive/simple/sphere.hpp +++ b/primitive_process/interface/primitive/simple/sphere.hpp @@ -11,13 +11,13 @@ struct sphere_t final : primitive { primitive_type get_type() const override { return PRIMITIVE_TYPE_SPHERE; }; - marked_subface_ptr_t sphere_face{}; - -protected: - void initialize(primitive_data_center_t &, const std::vector> &) override; + stl_vector_mp> get_subfaces() const override + { + return {static_pointer_cast(sphere_face)}; + } - marked_subface_ptr_t *get_subface() const override { return (marked_subface_ptr_t *)(&sphere_face); } + stl_vector_mp get_subface_types() const override { return {surface_type::sphere}; } - size_t get_subface_count() const override { return 1; } + marked_subface_ptr_t sphere_face{}; }; } // namespace internal \ No newline at end of file diff --git a/primitive_process/interface/primitive_descriptor.h b/primitive_process/interface/primitive_descriptor.h index de0246a..76d4ed6 100644 --- a/primitive_process/interface/primitive_descriptor.h +++ b/primitive_process/interface/primitive_descriptor.h @@ -13,7 +13,8 @@ typedef enum { PRIMITIVE_TYPE_BOX, // PRIMITIVE_TYPE_MESH, PRIMITIVE_TYPE_EXTRUDE_POLYLINE, - PRIMITIVE_TYPE_EXTRUDE_HELIXLINE + PRIMITIVE_TYPE_EXTRUDE_HELIXLINE, + PRIMITIVE_TYPE_MAX_COUNT } primitive_type; // // Placeholder, currently used to represent empty body diff --git a/primitive_process/interface/subface/simple/cylinder_face.hpp b/primitive_process/interface/subface/simple/cylinder_face.hpp index 5d86b1f..5f20cb4 100644 --- a/primitive_process/interface/subface/simple/cylinder_face.hpp +++ b/primitive_process/interface/subface/simple/cylinder_face.hpp @@ -22,41 +22,33 @@ struct cylinder_face_t final : subface { double v) const override; std::function fetch_solver_evaluator() const override; }; - -struct cylinder_paired_model_matrix { - internal::paired_model_matrix *data{}; -}; } // namespace internal namespace detail { +struct cylinder_surface_tag{}; + template <> -struct hasher { - size_t operator()(const internal::cylinder_paired_model_matrix &block) const +struct tagged_hasher { + size_t operator()(const internal::paired_model_matrix& block) const { - const auto& mat = block.data->local_to_world.matrix(); // 3x4 - Eigen::Matrix3d A = mat.block<3,3>(0,0); - Eigen::Vector3d b = mat.col(3); - - Eigen::Matrix3d B = A.inverse(); - Eigen::Matrix R = B.topRows<2>(); - - Eigen::Matrix3d G = R.transpose() * R; - Eigen::Vector2d zero_proj = R * b; - - size_t h = XXH3_64bits(G.data(), sizeof(Eigen::Matrix3d)); - h ^= XXH3_64bits(zero_proj.data(), sizeof(Eigen::Vector2d)); - - return h; + auto R = block.world_to_local.linear().topLeftCorner<2, 3>(); // 2x3 + auto b = block.local_to_world.translation(); // 3x1 + + Eigen::Matrix hash_mat = Eigen::Matrix3d::Zero(); + hash_mat.topLeftCorner<3, 3>() = R.transpose() * R; + hash_mat.topRightCorner<2, 1>() = R * b; + + return hash_funcs(hash_mat); } }; template <> -struct default_elem_ctor { - internal::cylinder_face_t operator()(const internal::cylinder_paired_model_matrix &k) const +struct default_elem_ctor { + internal::cylinder_face_t operator()(internal::paired_model_matrix& k) const { internal::cylinder_face_t res{}; - res.model_matrices = const_cast(k.data); + res.model_matrices = make_pointer_wrapper(k); return res; } }; diff --git a/primitive_process/interface/subface/simple/plane.hpp b/primitive_process/interface/subface/simple/plane.hpp index 698d806..f0b2d0c 100644 --- a/primitive_process/interface/subface/simple/plane.hpp +++ b/primitive_process/interface/subface/simple/plane.hpp @@ -22,32 +22,33 @@ struct plane_t final : subface { double v) const override; std::function fetch_solver_evaluator() const override; }; - -struct plane_paired_model_matrix { - internal::paired_model_matrix *data{}; -}; } // namespace internal namespace detail { +struct plane_surface_tag { +}; + template <> -struct hasher { - size_t operator()(const internal::plane_paired_model_matrix &block) const +struct tagged_hasher { + // TODO: only plane surface should have sign problem + size_t operator()(const internal::paired_model_matrix &block) const { - const auto& mat = block.data->local_to_world.matrix(); - Eigen::Matrix character_col; - character_col.col(0) = mat.col(0); - character_col.col(1) = mat.col(3); - return XXH3_64bits(character_col.data(), sizeof(Eigen::Matrix)); + const auto &mat = block.local_to_world.matrix(); + Eigen::Vector3d normal = mat.col(1).cross(mat.col(2)).normalized(); + if (normal.x() < 0 || (normal.x() == 0 && normal.y() < 0) || (normal.x() == 0 && normal.y() == 0 && normal.z() < 0)) { + normal = -normal; + } + return hash_funcs(normal); } }; template <> -struct default_elem_ctor { - internal::plane_t operator()(const internal::plane_paired_model_matrix &k) const +struct default_elem_ctor { + internal::plane_t operator()(internal::paired_model_matrix_ptr_t &k) const { internal::plane_t res{}; - res.model_matrices = const_cast(k.data); + res.model_matrices = make_pointer_wrapper(k); return res; } }; diff --git a/primitive_process/interface/subface/simple/sphere_face.hpp b/primitive_process/interface/subface/simple/sphere_face.hpp index 2b0a12b..60e4c9b 100644 --- a/primitive_process/interface/subface/simple/sphere_face.hpp +++ b/primitive_process/interface/subface/simple/sphere_face.hpp @@ -26,12 +26,16 @@ struct sphere_face_t final : subface { namespace detail { +struct sphere_surface_tag +{ +}; + template <> -struct default_elem_ctor { - internal::sphere_face_t operator()(const internal::paired_model_matrix *k) const +struct default_elem_ctor { + internal::sphere_face_t operator()(internal::paired_model_matrix& k) const { internal::sphere_face_t res{}; - res.model_matrices = const_cast(k); + res.model_matrices = make_pointer_wrapper(k); return res; } }; diff --git a/primitive_process/src/base/primitive.cpp b/primitive_process/src/base/primitive.cpp index 16a9c36..bdc0936 100644 --- a/primitive_process/src/base/primitive.cpp +++ b/primitive_process/src/base/primitive.cpp @@ -29,10 +29,10 @@ dynamic_bitset_mp<> primitive::judge_sign_by_subface_sign(stl_vector_mp> subface_signs) const { - auto subfaces = get_subface(); + auto subfaces = get_subfaces(); dynamic_bitset_mp<> res = subface_signs.front(); - for (size_t i = 1; i < get_subface_count(); ++i) { + for (size_t i = 1; i < subfaces.size(); ++i) { if (!subfaces[i].is_marked()) res |= subface_signs[i]; else @@ -42,22 +42,13 @@ dynamic_bitset_mp<> primitive::judge_sign_by_subface_sign(stl_vector_mp> new_model_matrices{}; - new_model_matrices.reserve(subface_count); - for (size_t i = 0; i < subface_count; ++i) { - auto subface_ptr = subfaces[i].get_ptr(); - new_model_matrices.emplace_back(subface_ptr->apply_transform(type, param)); - } + auto subfaces = get_subfaces(); + + stl_vector_mp new_model_matrices{}; + new_model_matrices.reserve(subfaces.size()); + for (size_t i = 0; i < subfaces.size(); ++i) { new_model_matrices.emplace_back(subfaces[i]->apply_transform(type, param)); } // aabb Eigen::Affine3d affine = Eigen::Affine3d::Identity(); @@ -76,5 +67,21 @@ void primitive::apply_transform(internal::transform_type type, Eigen::Vector4d p } m_aabb = m_aabb.transformed(affine); - initialize(*subfaces[0].get_ptr()->data_center, new_model_matrices); + initialize(subfaces[0]->data_center, new_model_matrices); +} + +void primitive::initialize(primitive_data_center_t &data_center, + const stl_vector_mp &new_matrices) +{ + auto old_subfaces = get_subfaces(); + auto subface_types = get_subface_types(); + + internal::paired_model_matrix_ptr_t old_matrix{}; + for (size_t i = 0; i < old_subfaces.size(); ++i) { + if (old_subfaces[i]) old_matrix = old_subfaces[i]->model_matrices; + + data_center.require_surface(subface_types[i], new_matrices[i], old_subfaces[i]); + + if (old_subfaces[i]) data_center.release_transform_block(old_matrix); + } } \ No newline at end of file diff --git a/primitive_process/src/base/subface.cpp b/primitive_process/src/base/subface.cpp index 0973c63..d50c80e 100644 --- a/primitive_process/src/base/subface.cpp +++ b/primitive_process/src/base/subface.cpp @@ -6,7 +6,7 @@ subface::~subface() noexcept { if (!data_center) return; - data_center->transform_blocks.release(*model_matrices); + data_center->transform_blocks.release(model_matrices); } internal::transform_block &subface::raw_local_to_world() const { return model_matrices->local_to_world; } @@ -17,9 +17,9 @@ Eigen::Vector3d subface::local_to_world_scale() const { return model_matrices->l Eigen::Matrix3d subface::trans_world_to_local_linear() const { return model_matrices->world_to_local.linear().transpose(); } -std::pair subface::apply_transform(internal::transform_type type, Eigen::Vector4d param) +internal::paired_model_matrix_ptr_t subface::apply_transform(internal::transform_type type, Eigen::Vector4d param) { - auto temp = *model_matrices; + auto temp = model_matrices.copy(); switch (type) { case internal::transform_type::scale: { temp.local_to_world.linear() = param.head<3>().asDiagonal() * temp.local_to_world.linear(); @@ -38,13 +38,6 @@ std::pair subface::apply_transform(intern default: throw std::invalid_argument("Invalid transform type"); } - bool reversed{}; - if (temp.world_to_local.data()[0] < 0) { - temp.local_to_world.matrix() *= -1; - temp.world_to_local.matrix() *= -1; - reversed = true; - } - auto [iter, _] = data_center->transform_blocks.acquire(temp); - return {iter.operator->(), reversed}; + return make_pointer_wrapper(iter.operator->()); } \ No newline at end of file diff --git a/primitive_process/src/data/data_center.cpp b/primitive_process/src/data/data_center.cpp index ac4abdf..a125d26 100644 --- a/primitive_process/src/data/data_center.cpp +++ b/primitive_process/src/data/data_center.cpp @@ -6,6 +6,11 @@ primitive_data_center_t::primitive_data_center_t() noexcept this->transform_blocks.acquire(internal::identity_model_matrix); this->transform_blocks.acquire(internal::plane_to_z_pos_1_model_matrix); this->transform_blocks.acquire(internal::plane_to_z_neg_1_model_matrix); + + // set hashed refcount hive container to individual surface containers + this->surfaces[static_cast(surface_type::plane)].emplace(); + this->surfaces[static_cast(surface_type::sphere)].emplace(); + this->surfaces[static_cast(surface_type::cylinder)].emplace(); } primitive_data_center_t::~primitive_data_center_t() noexcept @@ -15,6 +20,80 @@ primitive_data_center_t::~primitive_data_center_t() noexcept this->transform_blocks.release(internal::plane_to_z_neg_1_model_matrix); } +auto primitive_data_center_t::require_transform_block(const internal::paired_model_matrix& matrix) + -> internal::paired_model_matrix_ptr_t +{ + auto [iter, _] = this->transform_blocks.acquire(matrix); + return make_pointer_wrapper(iter.operator->()); +} + +void primitive_data_center_t::require_surface(surface_type type, + const internal::paired_model_matrix_ptr_t& matrix, + marked_subface_ptr_t& subface) +{ + switch (type) { + case surface_type::plane: { + auto [iter, is_new] = std::get(this->surfaces[static_cast(type)]).acquire(matrix); + subface.set_ptr(iter.operator->()); + subface.set_mark(false); + if (is_new) subface.get_ptr()->data_center = make_pointer_wrapper(this); + break; + } + case surface_type::sphere: { + auto [iter, is_new] = std::get(this->surfaces[static_cast(type)]).acquire(matrix); + subface.set_ptr(iter.operator->()); + subface.set_mark(false); + if (is_new) subface.get_ptr()->data_center = make_pointer_wrapper(this); + break; + } + case surface_type::cylinder: { + auto [iter, is_new] = std::get(this->surfaces[static_cast(type)]).acquire(matrix); + subface.set_ptr(iter.operator->()); + subface.set_mark(false); + if (is_new) subface.get_ptr()->data_center = make_pointer_wrapper(this); + break; + } + default: + subface.set_ptr(nullptr); + subface.set_mark(false); + break; + } +} + +void primitive_data_center_t::release_transform_block(const internal::paired_model_matrix& matrix) +{ + this->transform_blocks.release(matrix); +} + +void primitive_data_center_t::release_surface(surface_type type, const marked_subface_ptr_t& subface) +{ + switch (type) { + case surface_type::plane: + { + auto model_matrices = subface->model_matrices; + std::get(this->surfaces[static_cast(type)]).release(model_matrices); + release_transform_block(model_matrices); + break; + } + case surface_type::sphere: + { + auto model_matrices = subface->model_matrices; + std::get(this->surfaces[static_cast(type)]).release(model_matrices); + release_transform_block(model_matrices); + break; + } + case surface_type::cylinder: + { + auto model_matrices = subface->model_matrices; + std::get(this->surfaces[static_cast(type)]).release(model_matrices); + release_transform_block(model_matrices); + break; + } + default: + break; + } +} + namespace internal { PE_API primitive* new_primitive(primitive_type type) diff --git a/primitive_process/src/primitive/simple/cylinder.cpp b/primitive_process/src/primitive/simple/cylinder.cpp index 20623a6..856d02c 100644 --- a/primitive_process/src/primitive/simple/cylinder.cpp +++ b/primitive_process/src/primitive/simple/cylinder.cpp @@ -4,61 +4,59 @@ 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_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, - {std::pair(cylinder_iter.operator->(), false), - std::pair(bottom_plane_iter.operator->(), true), - std::pair(top_plane_iter.operator->(), false)}); + auto bottom_plane_mat = data_center.require_transform_block(internal::plane_to_z_model_matrix); + auto cylinder_mat = data_center.require_transform_block(internal::identity_model_matrix); + auto top_plane_mat = data_center.require_transform_block(internal::plane_to_z_pos_1_model_matrix); + primitive::initialize(data_center, {cylinder_mat, bottom_plane_mat, top_plane_mat}); } void cylinder_t::destroy() { - auto data_center = bottom_plane.get_ptr()->data_center; - data_center->planes.release(plane_paired_model_matrix{bottom_plane.get_ptr()->model_matrices}); + primitive_data_center_t &data_center = bottom_plane.get_ptr()->data_center; - data_center->planes.release(plane_paired_model_matrix{top_plane.get_ptr()->model_matrices}); + data_center.release_surface(surface_type::cylinder, static_pointer_cast(cylinder_face)); + data_center.release_surface(surface_type::plane, static_pointer_cast(bottom_plane)); + data_center.release_surface(surface_type::plane, static_pointer_cast(top_plane)); } -void cylinder_t::initialize(primitive_data_center_t &data_center, - const std::vector> &new_model_matrices) -{ - std::array old_ptrs{cylinder_face.get_ptr(), bottom_plane.get_ptr(), top_plane.get_ptr()}; - std::array old_model_matrices{nullptr, nullptr, nullptr}; - for (size_t i = 0; i < 3; ++i) { - if (old_ptrs[i] != nullptr) old_model_matrices[i] = old_ptrs[i]->model_matrices; - } - - { - auto [iter, is_new] = data_center.cylinders.acquire(cylinder_paired_model_matrix{new_model_matrices[0].first}); - cylinder_face.set_ptr(iter.operator->()); - cylinder_face.set_mark(new_model_matrices[0].second); - if (is_new) cylinder_face.get_ptr()->data_center = &data_center; - } - - { - auto [iter, is_new] = data_center.planes.acquire(plane_paired_model_matrix{new_model_matrices[1].first}); - bottom_plane.set_ptr(iter.operator->()); - bottom_plane.set_mark(new_model_matrices[1].second); - if (is_new) bottom_plane.get_ptr()->data_center = &data_center; - } - - { - auto [iter, is_new] = data_center.planes.acquire(plane_paired_model_matrix{new_model_matrices[2].first}); - top_plane.set_ptr(iter.operator->()); - top_plane.set_mark(new_model_matrices[2].second); - if (is_new) top_plane.get_ptr()->data_center = &data_center; - } - - // deferred release to avoid acquiring the same just-released subface - { - if (old_ptrs[0] != nullptr) - data_center.cylinders.release(cylinder_paired_model_matrix{old_model_matrices[0]}); - if (old_ptrs[1] != nullptr) - data_center.planes.release(plane_paired_model_matrix{old_model_matrices[1]}); - if (old_ptrs[2] != nullptr) - data_center.planes.release(plane_paired_model_matrix{old_model_matrices[2]}); - } -} +// void cylinder_t::initialize(primitive_data_center_t &data_center, +// const std::vector> &new_model_matrices) +// { +// std::array old_ptrs{cylinder_face.get_ptr(), bottom_plane.get_ptr(), top_plane.get_ptr()}; +// std::array old_model_matrices{nullptr, nullptr, nullptr}; +// for (size_t i = 0; i < 3; ++i) { +// if (old_ptrs[i] != nullptr) old_model_matrices[i] = old_ptrs[i]->model_matrices; +// } + +// { +// auto [iter, is_new] = data_center.cylinders.acquire(cylinder_paired_model_matrix{new_model_matrices[0].first}); +// cylinder_face.set_ptr(iter.operator->()); +// cylinder_face.set_mark(new_model_matrices[0].second); +// if (is_new) cylinder_face.get_ptr()->data_center = &data_center; +// } + +// { +// auto [iter, is_new] = data_center.planes.acquire(plane_paired_model_matrix{new_model_matrices[1].first}); +// bottom_plane.set_ptr(iter.operator->()); +// bottom_plane.set_mark(new_model_matrices[1].second); +// if (is_new) bottom_plane.get_ptr()->data_center = &data_center; +// } + +// { +// auto [iter, is_new] = data_center.planes.acquire(plane_paired_model_matrix{new_model_matrices[2].first}); +// top_plane.set_ptr(iter.operator->()); +// top_plane.set_mark(new_model_matrices[2].second); +// if (is_new) top_plane.get_ptr()->data_center = &data_center; +// } + +// // deferred release to avoid acquiring the same just-released subface +// { +// if (old_ptrs[0] != nullptr) +// data_center.cylinders.release(cylinder_paired_model_matrix{old_model_matrices[0]}); +// if (old_ptrs[1] != nullptr) +// data_center.planes.release(plane_paired_model_matrix{old_model_matrices[1]}); +// if (old_ptrs[2] != nullptr) +// data_center.planes.release(plane_paired_model_matrix{old_model_matrices[2]}); +// } +// } } // namespace internal \ No newline at end of file diff --git a/primitive_process/src/primitive/simple/sphere.cpp b/primitive_process/src/primitive/simple/sphere.cpp index e42a4bd..0c5f4a5 100644 --- a/primitive_process/src/primitive/simple/sphere.cpp +++ b/primitive_process/src/primitive/simple/sphere.cpp @@ -4,29 +4,28 @@ namespace internal { void sphere_t::initialize(primitive_data_center_t &data_center) { - auto [iter, _] = data_center.transform_blocks.acquire(internal::identity_model_matrix); - initialize(data_center, {std::pair(iter.operator->(), false)}); + primitive::initialize(data_center, {data_center.require_transform_block(internal::identity_model_matrix)}); } void sphere_t::destroy() { - auto data_center = sphere_face.get_ptr()->data_center; - data_center->spheres.release(sphere_face.get_ptr()->model_matrices); + primitive_data_center_t& data_center = sphere_face->data_center; + data_center.release_surface(surface_type::sphere, static_pointer_cast(sphere_face)); } -void sphere_t::initialize(primitive_data_center_t &data_center, - const std::vector> &new_model_matrices) -{ - auto old_ptr = sphere_face.get_ptr(); - paired_model_matrix *old_model_matrices{nullptr}; - if (old_ptr != nullptr) old_model_matrices = old_ptr->model_matrices; +// void sphere_t::initialize(primitive_data_center_t &data_center, +// const std::vector> &new_model_matrices) +// { +// auto old_ptr = sphere_face.get_ptr(); +// paired_model_matrix *old_model_matrices{nullptr}; +// if (old_ptr != nullptr) old_model_matrices = old_ptr->model_matrices; - auto [iter, is_new] = data_center.spheres.acquire(new_model_matrices[0].first); - sphere_face.set_ptr(iter.operator->()); - sphere_face.set_mark(new_model_matrices[0].second); - if (is_new) sphere_face.get_ptr()->data_center = &data_center; +// auto [iter, is_new] = data_center.spheres.acquire(new_model_matrices[0].first); +// sphere_face.set_ptr(iter.operator->()); +// sphere_face.set_mark(new_model_matrices[0].second); +// if (is_new) sphere_face.get_ptr()->data_center = &data_center; - // deferred release to avoid acquiring the same just-released subface - if (old_ptr != nullptr) data_center.spheres.release(old_model_matrices); -} +// // deferred release to avoid acquiring the same just-released subface +// if (old_ptr != nullptr) data_center.spheres.release(old_model_matrices); +// } } // namespace internal \ No newline at end of file diff --git a/primitive_process/src/subface/simple/cylinder_face.cpp b/primitive_process/src/subface/simple/cylinder_face.cpp index cbd4db5..d243913 100644 --- a/primitive_process/src/subface/simple/cylinder_face.cpp +++ b/primitive_process/src/subface/simple/cylinder_face.cpp @@ -4,8 +4,8 @@ namespace internal { auto cylinder_face_t::fetch_sdf_evaluator() const -> std::function { - auto functor = [](Eigen::Vector3d p, Eigen::Vector3d local_to_world_scale, const transform_block* _world_to_local) { - Eigen::Vector4d local_p = *_world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; + auto functor = [](Eigen::Vector3d p, Eigen::Vector3d local_to_world_scale, const transform_block& _world_to_local) { + Eigen::Vector4d local_p = _world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; const double len = local_p.head<2>().norm(); if (len > std::numeric_limits::epsilon()) { @@ -16,29 +16,29 @@ auto cylinder_face_t::fetch_sdf_evaluator() const -> std::functionlocal_to_world_scale(), &this->raw_world_to_local()); + return std::bind(functor, std::placeholders::_1, this->local_to_world_scale(), std::ref(this->raw_world_to_local())); } auto cylinder_face_t::fetch_sdf_grad_evaluator() const -> std::function { - auto functor = [](Eigen::Vector3d p, Eigen::Matrix3d trans_world_to_local_linear, const transform_block* _world_to_local) { - Eigen::Vector4d local_p = *_world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; + auto functor = [](Eigen::Vector3d p, Eigen::Matrix3d trans_world_to_local_linear, const transform_block& _world_to_local) { + Eigen::Vector4d local_p = _world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; Eigen::Vector2d normal = local_p.head<2>().normalized(); return trans_world_to_local_linear * Eigen::Vector3d{normal.x(), normal.y(), 0.0}; }; - return std::bind(functor, std::placeholders::_1, this->trans_world_to_local_linear(), &this->raw_world_to_local()); + return std::bind(functor, std::placeholders::_1, this->trans_world_to_local_linear(), std::ref(this->raw_world_to_local())); } auto cylinder_face_t::fetch_point_by_param_evaluator() const -> std::function { - auto functor = [](double u, double v, const transform_block* _local_to_world) { + auto functor = [](double u, double v, const transform_block& _local_to_world) { const auto cos_u = std::cos(u); const auto sin_u = std::sin(u); - return *_local_to_world * Eigen::Vector4d(cos_u, v, sin_u, 1.0); + return _local_to_world * Eigen::Vector4d(cos_u, v, sin_u, 1.0); }; - return std::bind(functor, std::placeholders::_1, std::placeholders::_2, &this->raw_local_to_world()); + return std::bind(functor, std::placeholders::_1, std::placeholders::_2, std::ref(this->raw_local_to_world())); } auto cylinder_face_t::fetch_curve_constraint_evaluator(parameter_u_t constraint_var_type, double u) const @@ -47,44 +47,44 @@ auto cylinder_face_t::fetch_curve_constraint_evaluator(parameter_u_t constraint_ const auto cos_u = std::cos(u); const auto sin_u = std::sin(u); - auto functor = [&](double v, const transform_block* _local_to_world) { + auto functor = [&](double v, const transform_block& _local_to_world) { constraint_curve_intermediate res{}; - res.f = *_local_to_world * Eigen::Vector4d(cos_u, v, sin_u, 1.0); - res.grad_f = *_local_to_world * Eigen::Vector4d(0, 1, 0, 0.0); + res.f = _local_to_world * Eigen::Vector4d(cos_u, v, sin_u, 1.0); + res.grad_f = _local_to_world * Eigen::Vector4d(0, 1, 0, 0.0); return res; }; - return std::bind(functor, std::placeholders::_1, &this->raw_local_to_world()); + return std::bind(functor, std::placeholders::_1, std::ref(this->raw_local_to_world())); } auto cylinder_face_t::fetch_curve_constraint_evaluator(parameter_v_t constraint_var_type, double v) const -> std::function { - auto functor = [&](double u, const transform_block* _local_to_world) { + auto functor = [&](double u, const transform_block& _local_to_world) { auto cos_u = std::cos(u); auto sin_u = std::sin(u); constraint_curve_intermediate res{}; - res.f = *_local_to_world * Eigen::Vector4d(cos_u, v, sin_u, 1.0); - res.grad_f = *_local_to_world * Eigen::Vector4d(-sin_u, 0.0, cos_u, 0.0); + res.f = _local_to_world * Eigen::Vector4d(cos_u, v, sin_u, 1.0); + res.grad_f = _local_to_world * Eigen::Vector4d(-sin_u, 0.0, cos_u, 0.0); return res; }; - return std::bind(functor, std::placeholders::_1, &this->raw_local_to_world()); + return std::bind(functor, std::placeholders::_1, std::ref(this->raw_local_to_world())); } auto cylinder_face_t::fetch_solver_evaluator() const -> std::function { - auto functor = [](constraint_curve_intermediate&& temp_res, const transform_block* _world_to_local) { + auto functor = [](constraint_curve_intermediate&& temp_res, const transform_block& _world_to_local) { implicit_equation_intermediate res{}; - Eigen::Vector3d local_f = (*_world_to_local * temp_res.f).head<3>(); + Eigen::Vector3d local_f = (_world_to_local * temp_res.f).head<3>(); res.f = local_f.head<2>().squaredNorm() - 1; - res.df = 2 * local_f.head<2>().dot((*_world_to_local * temp_res.grad_f).head<2>()); + res.df = 2 * local_f.head<2>().dot((_world_to_local * temp_res.grad_f).head<2>()); return res; }; - return std::bind(functor, std::placeholders::_1, &this->raw_world_to_local()); + return std::bind(functor, std::placeholders::_1, std::ref(this->raw_world_to_local())); } } // namespace internal \ No newline at end of file diff --git a/primitive_process/src/subface/simple/plane.cpp b/primitive_process/src/subface/simple/plane.cpp index 4eb170b..79e3b68 100644 --- a/primitive_process/src/subface/simple/plane.cpp +++ b/primitive_process/src/subface/simple/plane.cpp @@ -4,70 +4,70 @@ namespace internal { auto plane_t::fetch_sdf_evaluator() const -> std::function { - auto functor = [](Eigen::Vector3d p, Eigen::Vector3d local_to_world_scale, const transform_block* _world_to_local) { - Eigen::Vector4d local_p = *_world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; + auto functor = [](Eigen::Vector3d p, Eigen::Vector3d local_to_world_scale, const transform_block& _world_to_local) { + Eigen::Vector4d local_p = _world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; return local_to_world_scale.x() * local_p.x(); }; - return std::bind(functor, std::placeholders::_1, this->local_to_world_scale(), &this->raw_world_to_local()); + return std::bind(functor, std::placeholders::_1, this->local_to_world_scale(), std::ref(this->raw_world_to_local())); } auto plane_t::fetch_sdf_grad_evaluator() const -> std::function { - auto functor = [](Eigen::Vector3d p, Eigen::Matrix3d trans_world_to_local_linear, const transform_block* _world_to_local) { + auto functor = [](Eigen::Vector3d p, Eigen::Matrix3d trans_world_to_local_linear, const transform_block& _world_to_local) { return trans_world_to_local_linear * Eigen::Vector3d{1, 0, 0}; }; - return std::bind(functor, std::placeholders::_1, this->trans_world_to_local_linear(), &this->raw_world_to_local()); + return std::bind(functor, std::placeholders::_1, this->trans_world_to_local_linear(), std::ref(this->raw_world_to_local())); } auto plane_t::fetch_point_by_param_evaluator() const -> std::function { - auto functor = [](double u, double v, const transform_block* _local_to_world) { - return *_local_to_world * Eigen::Vector4d(0, u, v, 1.0); + auto functor = [](double u, double v, const transform_block& _local_to_world) { + return _local_to_world * Eigen::Vector4d(0, u, v, 1.0); }; - return std::bind(functor, std::placeholders::_1, std::placeholders::_2, &this->raw_local_to_world()); + return std::bind(functor, std::placeholders::_1, std::placeholders::_2, std::ref(this->raw_local_to_world())); } auto plane_t::fetch_curve_constraint_evaluator(parameter_u_t constraint_var_type, double u) const -> std::function { - auto functor = [&](double v, const transform_block* _local_to_world) { + auto functor = [&](double v, const transform_block& _local_to_world) { constraint_curve_intermediate res{}; - res.f = *_local_to_world * Eigen::Vector4d(0, u, v, 1.0); - res.grad_f = *_local_to_world * Eigen::Vector4d(0, 0, 1, 0.0); + res.f = _local_to_world * Eigen::Vector4d(0, u, v, 1.0); + res.grad_f = _local_to_world * Eigen::Vector4d(0, 0, 1, 0.0); return res; }; - return std::bind(functor, std::placeholders::_1, &this->raw_local_to_world()); + return std::bind(functor, std::placeholders::_1, std::ref(this->raw_local_to_world())); } auto plane_t::fetch_curve_constraint_evaluator(parameter_v_t constraint_var_type, double v) const -> std::function { - auto functor = [&](double u, const transform_block* _local_to_world) { + auto functor = [&](double u, const transform_block& _local_to_world) { constraint_curve_intermediate res{}; - res.f = *_local_to_world * Eigen::Vector4d(0, u, v, 1.0); - res.grad_f = *_local_to_world * Eigen::Vector4d(0, 1, 0, 0.0); + res.f = _local_to_world * Eigen::Vector4d(0, u, v, 1.0); + res.grad_f = _local_to_world * Eigen::Vector4d(0, 1, 0, 0.0); return res; }; - return std::bind(functor, std::placeholders::_1, &this->raw_local_to_world()); + return std::bind(functor, std::placeholders::_1, std::ref(this->raw_local_to_world())); } auto plane_t::fetch_solver_evaluator() const -> std::function { - auto functor = [](constraint_curve_intermediate&& temp_res, const transform_block* _world_to_local) { + auto functor = [](constraint_curve_intermediate&& temp_res, const transform_block& _world_to_local) { implicit_equation_intermediate res{}; - Eigen::Vector3d local_f = (*_world_to_local * temp_res.f).head<3>(); + Eigen::Vector3d local_f = (_world_to_local * temp_res.f).head<3>(); res.f = local_f.x(); - res.df = (*_world_to_local * temp_res.grad_f).x(); + res.df = (_world_to_local * temp_res.grad_f).x(); return res; }; - return std::bind(functor, std::placeholders::_1, &this->raw_world_to_local()); + return std::bind(functor, std::placeholders::_1, std::ref(this->raw_world_to_local())); } } // namespace internal \ No newline at end of file diff --git a/primitive_process/src/subface/simple/sphere_face.cpp b/primitive_process/src/subface/simple/sphere_face.cpp index 60c44df..9e46996 100644 --- a/primitive_process/src/subface/simple/sphere_face.cpp +++ b/primitive_process/src/subface/simple/sphere_face.cpp @@ -4,8 +4,8 @@ namespace internal { auto sphere_face_t::fetch_sdf_evaluator() const -> std::function { - auto functor = [](Eigen::Vector3d p, Eigen::Vector3d local_to_world_scale, const transform_block* _world_to_local) { - Eigen::Vector4d local_p = *_world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; + auto functor = [](Eigen::Vector3d p, Eigen::Vector3d local_to_world_scale, const transform_block& _world_to_local) { + Eigen::Vector4d local_p = _world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; const double len = local_p.head<3>().norm(); if (len > std::numeric_limits::epsilon()) { @@ -16,31 +16,31 @@ auto sphere_face_t::fetch_sdf_evaluator() const -> std::functionlocal_to_world_scale(), &this->raw_world_to_local()); + return std::bind(functor, std::placeholders::_1, this->local_to_world_scale(), std::ref(this->raw_world_to_local())); } auto sphere_face_t::fetch_sdf_grad_evaluator() const -> std::function { - auto functor = [](Eigen::Vector3d p, Eigen::Matrix3d trans_world_to_local_linear, const transform_block* _world_to_local) { - Eigen::Vector4d local_p = *_world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; + auto functor = [](Eigen::Vector3d p, Eigen::Matrix3d trans_world_to_local_linear, const transform_block& _world_to_local) { + Eigen::Vector4d local_p = _world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; Eigen::Vector3d normal = local_p.head<3>().normalized(); return trans_world_to_local_linear * normal; }; - return std::bind(functor, std::placeholders::_1, this->trans_world_to_local_linear(), &this->raw_world_to_local()); + return std::bind(functor, std::placeholders::_1, this->trans_world_to_local_linear(), std::ref(this->raw_world_to_local())); } auto sphere_face_t::fetch_point_by_param_evaluator() const -> std::function { - auto functor = [](double u, double v, const transform_block* _local_to_world) { + auto functor = [](double u, double v, const transform_block& _local_to_world) { const auto cos_u = std::cos(u); const auto sin_u = std::sin(u); const auto cos_v = std::cos(v); const auto sin_v = std::sin(v); - return *_local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.0); + return _local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.0); }; - return std::bind(functor, std::placeholders::_1, std::placeholders::_2, &this->raw_local_to_world()); + return std::bind(functor, std::placeholders::_1, std::placeholders::_2, std::ref(this->raw_local_to_world())); } auto sphere_face_t::fetch_curve_constraint_evaluator(parameter_u_t constraint_var_type, double u) const @@ -49,18 +49,18 @@ auto sphere_face_t::fetch_curve_constraint_evaluator(parameter_u_t constraint_va const auto cos_u = std::cos(u); const auto sin_u = std::sin(u); - auto functor = [&](double v, const transform_block* _local_to_world) { + auto functor = [&](double v, const transform_block& _local_to_world) { auto cos_v = std::cos(v); auto sin_v = std::sin(v); constraint_curve_intermediate res{}; - res.f = *_local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.0); - res.grad_f = *_local_to_world * Eigen::Vector4d(cos_u * -sin_v, cos_v, sin_u * -sin_v, 0.0); + res.f = _local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.0); + res.grad_f = _local_to_world * Eigen::Vector4d(cos_u * -sin_v, cos_v, sin_u * -sin_v, 0.0); return res; }; - return std::bind(functor, std::placeholders::_1, &this->raw_local_to_world()); + return std::bind(functor, std::placeholders::_1, std::ref(this->raw_local_to_world())); } auto sphere_face_t::fetch_curve_constraint_evaluator(parameter_v_t constraint_var_type, double v) const @@ -69,30 +69,30 @@ auto sphere_face_t::fetch_curve_constraint_evaluator(parameter_v_t constraint_va const auto cos_v = std::cos(v); const auto sin_v = std::sin(v); - auto functor = [&](double u, const transform_block* _local_to_world) { + auto functor = [&](double u, const transform_block& _local_to_world) { auto cos_u = std::cos(u); auto sin_u = std::sin(u); constraint_curve_intermediate res{}; - res.f = *_local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.0); - res.grad_f = *_local_to_world * Eigen::Vector4d(-sin_u * cos_v, 0.0, cos_u * cos_v, 0.0); + res.f = _local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.0); + res.grad_f = _local_to_world * Eigen::Vector4d(-sin_u * cos_v, 0.0, cos_u * cos_v, 0.0); return res; }; - return std::bind(functor, std::placeholders::_1, &this->raw_local_to_world()); + return std::bind(functor, std::placeholders::_1, std::ref(this->raw_local_to_world())); } auto sphere_face_t::fetch_solver_evaluator() const -> std::function { - auto functor = [](constraint_curve_intermediate&& temp_res, const transform_block* _world_to_local) { + auto functor = [](constraint_curve_intermediate&& temp_res, const transform_block& _world_to_local) { implicit_equation_intermediate res{}; - Eigen::Vector3d local_f = (*_world_to_local * temp_res.f).head<3>(); + Eigen::Vector3d local_f = (_world_to_local * temp_res.f).head<3>(); res.f = local_f.squaredNorm() - 1; - res.df = 2 * local_f.dot((*_world_to_local * temp_res.grad_f).head<3>()); + res.df = 2 * local_f.dot((_world_to_local * temp_res.grad_f).head<3>()); return res; }; - return std::bind(functor, std::placeholders::_1, &this->raw_world_to_local()); + return std::bind(functor, std::placeholders::_1, std::ref(this->raw_world_to_local())); } } // namespace internal \ No newline at end of file diff --git a/shared_module/container/hashed_refcount_hive.hpp b/shared_module/container/hashed_refcount_hive.hpp index a7c5014..7e769d5 100644 --- a/shared_module/container/hashed_refcount_hive.hpp +++ b/shared_module/container/hashed_refcount_hive.hpp @@ -65,6 +65,59 @@ public: throw std::runtime_error("Pointer not found in refcount map."); } +protected: + hive data{}; + // manually calculate hash for the key, so that we do not need to store the key + flat_hash_map> refcount_data_map{}; +}; + +template +struct tagged_hasher; + +template > +struct tagged_hashed_refcount_hive { + using iterator = typename hive::iterator; + +public: + std::pair acquire(const K& key) + { + size_t hash_key = tagged_hasher()(key); + auto iter = refcount_data_map.find(hash_key); + if (iter == refcount_data_map.end()) { + auto data_iter = data.emplace(default_elem_ctor{}(key)); + refcount_data_map.emplace(hash_key, std::make_pair(1, data_iter)); + return {data_iter, true}; + } else { + iter->second.first += 1; + return {iter->second.second, false}; + } + } + + void release(const K& key) + { + size_t hash_key = tagged_hasher()(key); + auto iter = refcount_data_map.find(hash_key); + if (iter == refcount_data_map.end()) throw std::runtime_error("Key not found in refcount map."); + if (--iter->second.first == 0) { + data.erase(iter->second.second); + refcount_data_map.erase(iter); + } + } + + void release(const iterator& ptr) + { + for (auto iter = refcount_data_map.begin(); iter != refcount_data_map.end(); ++iter) { + if (iter->second.second == ptr) { + if (--iter->second.first == 0) { + data.erase(iter->second.second); + refcount_data_map.erase(iter); + } + return; + } + } + throw std::runtime_error("Pointer not found in refcount map."); + } + protected: hive data{}; // manually calculate hash for the key, so that we do not need to store the key @@ -73,4 +126,7 @@ protected: } // namespace detail template -using hashed_refcount_hive_mp = detail::hashed_refcount_hive>; \ No newline at end of file +using hashed_refcount_hive_mp = detail::hashed_refcount_hive>; + +template +using tagged_hashed_refcount_hive_mp = detail::tagged_hashed_refcount_hive>; \ No newline at end of file diff --git a/shared_module/utils/hash_ext.hpp b/shared_module/utils/hash_ext.hpp new file mode 100644 index 0000000..1105723 --- /dev/null +++ b/shared_module/utils/hash_ext.hpp @@ -0,0 +1,67 @@ +#pragma once + +#include +#include + +#include + +namespace detail +{ + template + struct float_to_int_type + { + static_assert(std::is_floating_point_v, "T must be a floating point type"); + using type = std::conditional_t; + }; + + static constexpr float float_hash_epsilon = 1e-6f; +} + +struct hash_funcs_fn +{ + template + size_t operator()(const Eigen::Matrix &mat) const + { + static_assert(M != Eigen::Dynamic && N != Eigen::Dynamic, "only fixed size matrix is supported"); + + if constexpr (std::is_integral_v) + return XXH3_64bits(mat.data(), sizeof(T) * M * N); + else if constexpr (std::is_floating_point_v) + { + using integral_type = typename detail::float_to_int_type::type; + Eigen::Matrix int_mat = (mat.array() / static_cast(detail::float_hash_epsilon)).template cast(); + return XXH3_64bits(int_mat.data(), sizeof(integral_type) * M * N); + } + else + static_assert([]() { return false; }(), "unsupported type in hash"); + } + + template + size_t operator()(const Eigen::Transform &trans) const + { + if constexpr (std::is_integral_v) + return XXH3_64bits(trans.data(), sizeof(T) * N * (N + 1)); + 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(); + return XXH3_64bits(int_mat.data(), sizeof(integral_type) * N * (N + 1)); + } + else + static_assert([]() { return false; }(), "unsupported type in hash"); + } + + template + size_t operator()(std::reference_wrapper ref) const + { + return size_t(std::addressof(ref.get())); + } + + template + size_t operator()(std::reference_wrapper ref) const + { + return size_t(std::addressof(ref.get())); + } +}; + +static constexpr hash_funcs_fn hash_funcs{}; \ No newline at end of file diff --git a/shared_module/utils/marked_ptr.hpp b/shared_module/utils/marked_ptr.hpp index ef2aa93..9d119ee 100644 --- a/shared_module/utils/marked_ptr.hpp +++ b/shared_module/utils/marked_ptr.hpp @@ -1,5 +1,6 @@ #pragma once +#include template struct marked_ptr { static constexpr size_t mask = (1 << bits_to_store) - 1; @@ -45,6 +46,14 @@ struct marked_ptr { operator bool() const { return is_marked(); } + T* operator->() const { return get_ptr(); } + protected: T* ptr{nullptr}; -}; \ No newline at end of file +}; + +template +inline static marked_ptr static_pointer_cast(const marked_ptr& p) +{ + return marked_ptr(static_cast(p.get_ptr()), p.get_mark()); +} \ No newline at end of file diff --git a/shared_module/utils/pointer_wrapper.hpp b/shared_module/utils/pointer_wrapper.hpp new file mode 100644 index 0000000..f91735c --- /dev/null +++ b/shared_module/utils/pointer_wrapper.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +template +struct pointer_wrapper{ + static_assert(std::is_object_v, "T must be an object type"); + + pointer_wrapper() noexcept = default; + explicit pointer_wrapper(T* p) noexcept : ptr(p) {} + explicit pointer_wrapper(T&& x) noexcept + { + T& ref = std::forward(x); + ptr = std::addressof(ref); + } + + T& get() const noexcept { return *ptr; } + auto operator->() const noexcept { return ptr; } + operator T&() const noexcept { return *ptr; } + + T copy() const noexcept { return *ptr; } + + auto raw() const noexcept -> T* { return ptr; } + operator bool() const noexcept { return ptr != nullptr; } + +private: + T* ptr{nullptr}; +}; + +template +auto make_pointer_wrapper(T* p) noexcept -> pointer_wrapper +{ + return pointer_wrapper(p); +} + +template +auto make_pointer_wrapper(T& x) noexcept -> pointer_wrapper +{ + return pointer_wrapper(x); +} \ No newline at end of file