Browse Source

more structured primitive description with improved initialization method;

maybe ECS framework can be used to gain more efficiency, but it's just fine for now
V2-origin
Zhicheng Wang 2 months ago
parent
commit
292cf6ffb8
  1. 9
      blobtree_structure/src/baked_blobtree.cpp
  2. 3
      network_process/src/prim_gen/extract_vertex_infos.cpp
  3. 16
      primitive_process/interface/base/primitive.hpp
  4. 8
      primitive_process/interface/base/subface.hpp
  5. 21
      primitive_process/interface/data/data_center.hpp
  6. 26
      primitive_process/interface/data/data_type.hpp
  7. 21
      primitive_process/interface/primitive/simple/cylinder.hpp
  8. 12
      primitive_process/interface/primitive/simple/sphere.hpp
  9. 3
      primitive_process/interface/primitive_descriptor.h
  10. 34
      primitive_process/interface/subface/simple/cylinder_face.hpp
  11. 29
      primitive_process/interface/subface/simple/plane.hpp
  12. 10
      primitive_process/interface/subface/simple/sphere_face.hpp
  13. 41
      primitive_process/src/base/primitive.cpp
  14. 15
      primitive_process/src/base/subface.cpp
  15. 79
      primitive_process/src/data/data_center.cpp
  16. 98
      primitive_process/src/primitive/simple/cylinder.cpp
  17. 33
      primitive_process/src/primitive/simple/sphere.cpp
  18. 42
      primitive_process/src/subface/simple/cylinder_face.cpp
  19. 40
      primitive_process/src/subface/simple/plane.cpp
  20. 42
      primitive_process/src/subface/simple/sphere_face.cpp
  21. 56
      shared_module/container/hashed_refcount_hive.hpp
  22. 67
      shared_module/utils/hash_ext.hpp
  23. 9
      shared_module/utils/marked_ptr.hpp
  24. 40
      shared_module/utils/pointer_wrapper.hpp

9
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); 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 = primitive_ptr;
auto subface_count = primitive_ptr->get_subface_count(); auto subfaces = primitive_ptr->get_subfaces();
auto subfaces_ptr = primitive_ptr->get_subface(); primitive.index_mapping.reserve(subfaces.size());
primitive.index_mapping.reserve(subface_count); for (size_t i = 0; i < subfaces.size(); ++i) {
for (size_t i = 0; i < subface_count; ++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_ptr[i].get_ptr(); subface.object_ptr = subfaces[i].get_ptr();
subface.index_mapping = {node.primitive_index}; subface.index_mapping = {node.primitive_index};
} }
} else { } else {

3
network_process/src/prim_gen/extract_vertex_infos.cpp

@ -1,8 +1,5 @@
#include <prim_gen.hpp> #include <prim_gen.hpp>
using aabb_t = Eigen::AlignedBox<double, 3>;
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<aabb_t>& primitive_boundings) aabb_t mark_primitive_boundings(double aabb_margin, const baked_blobtree_t& tree, stl_vector_mp<aabb_t>& primitive_boundings)
{ {
primitive_boundings.reserve(tree.primitives.size()); primitive_boundings.reserve(tree.primitives.size());

16
primitive_process/interface/base/primitive.hpp

@ -13,6 +13,7 @@
template <typename T> template <typename T>
using marked_subface_ptr_t = marked_ptr<T, 1>; using marked_subface_ptr_t = marked_ptr<T, 1>;
using aabb_t = Eigen::AlignedBox<double, 3>; using aabb_t = Eigen::AlignedBox<double, 3>;
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 }; 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 initialize(primitive_data_center_t &) = 0;
virtual void destroy() = 0; virtual void destroy() = 0;
virtual primitive_type get_type() const = 0; virtual primitive_type get_type() const = 0;
virtual marked_subface_ptr_t<subface> *get_subface() const = 0; virtual stl_vector_mp<marked_subface_ptr_t<subface>> get_subfaces() const = 0;
virtual size_t get_subface_count() const = 0; virtual stl_vector_mp<surface_type> get_subface_types() const = 0;
aabb_t m_aabb = aabb_t(Eigen::Vector3d(-1, -1, -1), Eigen::Vector3d(1, 1, 1));
// sign_t judge_sign_by_subface_sdf(const std::vector<double> &) const; // sign_t judge_sign_by_subface_sdf(const std::vector<double> &) const;
// sign_t judge_sign_by_subface_sdf_sign(const std::vector<sign_t> &) const; // sign_t judge_sign_by_subface_sdf_sign(const std::vector<sign_t> &) const;
dynamic_bitset_mp<> judge_sign_by_subface_sign(stl_vector_mp<dynamic_bitset_mp<>>) const; dynamic_bitset_mp<> judge_sign_by_subface_sign(stl_vector_mp<dynamic_bitset_mp<>>) const;
aabb_t fetch_aabb() const { return m_aabb; }
aabb_t fetch_aabb() const;
void apply_transform(internal::transform_type, Eigen::Vector4d); void apply_transform(internal::transform_type, Eigen::Vector4d);
protected: protected:
virtual void initialize(primitive_data_center_t &, void initialize(primitive_data_center_t &, const stl_vector_mp<internal::paired_model_matrix_ptr_t> &);
const std::vector<std::pair<internal::paired_model_matrix *, bool>> &) = 0;
aabb_t m_aabb{k_aabb_unit};
}; };

8
primitive_process/interface/base/subface.hpp

@ -67,8 +67,8 @@ EXTERN_C struct PE_API subface {
virtual std::function<internal::equation_intermediate_t(internal::constraint_curve_intermediate &&)> virtual std::function<internal::equation_intermediate_t(internal::constraint_curve_intermediate &&)>
fetch_solver_evaluator() const = 0; fetch_solver_evaluator() const = 0;
primitive_data_center_t *data_center{nullptr}; primitive_data_center_ptr_t data_center{};
internal::paired_model_matrix *model_matrices{nullptr}; internal::paired_model_matrix_ptr_t model_matrices{};
internal::transform_block &raw_local_to_world() const; internal::transform_block &raw_local_to_world() const;
internal::transform_block &raw_world_to_local() 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 // NOTE: to avoid any specialization, always keep the characteristic part in the first row/column, which should be impled by
// subface's presentation // subface's presentation
// return: [ptr to changed paired_model_matrix, is_reversed] // return: [ptr to changed paired_model_matrix, is_reversed]
std::pair<internal::paired_model_matrix *, bool> 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<internal::paired_model_matrix *, bool> apply_transform(internal::transform_type, Eigen::Vector4d);
internal::paired_model_matrix_ptr_t apply_transform(internal::transform_type, Eigen::Vector4d);
}; };

21
primitive_process/interface/data/data_center.hpp

@ -5,15 +5,28 @@
#include "primitive/simple/sphere.hpp" #include "primitive/simple/sphere.hpp"
#include "primitive/simple/cylinder.hpp" #include "primitive/simple/cylinder.hpp"
template <typename Surface, typename Tag>
using surface_container_t = tagged_hashed_refcount_hive_mp<internal::paired_model_matrix_ptr_t, Surface, Tag>;
using plane_container_t = surface_container_t<internal::plane_t, detail::plane_surface_tag>;
using sphere_container_t = surface_container_t<internal::sphere_face_t, detail::sphere_surface_tag>;
using cylinder_container_t = surface_container_t<internal::cylinder_face_t, detail::cylinder_surface_tag>;
EXTERN_C struct PE_API primitive_data_center_t { EXTERN_C struct PE_API primitive_data_center_t {
primitive_data_center_t() noexcept; primitive_data_center_t() noexcept;
~primitive_data_center_t() noexcept; ~primitive_data_center_t() noexcept;
hashed_refcount_hive_mp<internal::paired_model_matrix, internal::paired_model_matrix> transform_blocks{}; hashed_refcount_hive_mp<internal::paired_model_matrix, internal::paired_model_matrix> transform_blocks{};
// all other data depend on cached transform_blocks // all other data depend on cached transform_blocks
hashed_refcount_hive_mp<internal::plane_paired_model_matrix, internal::plane_t> planes{}; using surface_containers = std::variant<plane_container_t, sphere_container_t, cylinder_container_t>;
hashed_refcount_hive_mp<internal::paired_model_matrix*, internal::sphere_face_t> spheres{}; std::array<surface_containers, static_cast<uint8_t>(surface_type::max_count)> surfaces{};
hashed_refcount_hive_mp<internal::cylinder_paired_model_matrix, internal::cylinder_face_t> cylinders{};
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>& subface);
void release_transform_block(const internal::paired_model_matrix& matrix);
void release_surface(surface_type type, const marked_subface_ptr_t<subface>& subface);
}; };
namespace internal namespace internal

26
primitive_process/interface/data/data_type.hpp

@ -1,9 +1,9 @@
#pragma once #pragma once
#include <xxhash.h>
#include <math/eigen_alias.hpp> #include <math/eigen_alias.hpp>
#include <container/hashed_refcount_hive.hpp> #include <container/hashed_refcount_hive.hpp>
#include <utils/hash_ext.hpp>
#include <utils/pointer_wrapper.hpp>
namespace internal namespace internal
{ {
@ -16,6 +16,8 @@ struct paired_model_matrix {
transform_block world_to_local{internal::transform_block::Identity()}; transform_block world_to_local{internal::transform_block::Identity()};
}; };
using paired_model_matrix_ptr_t = pointer_wrapper<paired_model_matrix>;
const paired_model_matrix identity_model_matrix{internal::transform_block::Identity(), internal::transform_block::Identity()}; const paired_model_matrix identity_model_matrix{internal::transform_block::Identity(), internal::transform_block::Identity()};
const auto plane_to_z_pos_1_model_matrix = []() { const auto plane_to_z_pos_1_model_matrix = []() {
paired_model_matrix res{}; 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}; res.local_to_world.translation() = Eigen::Vector3d{0, 0, 1};
return res; return res;
}(); }();
const auto plane_to_z_model_matrix = []() { const auto plane_to_z_model_matrix = []() {
paired_model_matrix res{}; paired_model_matrix res{};
Eigen::Matrix3d::Identity(); Eigen::Matrix3d::Identity();
res.world_to_local.linear().col(0) = Eigen::Vector3d{0, 0, 1}; 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 } // namespace internal
struct primitive_data_center_t; struct primitive_data_center_t;
using primitive_data_center_ptr_t = pointer_wrapper<primitive_data_center_t>;
enum class surface_type : uint8_t { plane, sphere, cylinder, cone, max_count };
namespace detail namespace detail
{ {
template <> template <>
struct hasher<internal::transform_block> { struct hasher<internal::transform_block> {
size_t operator()(const internal::transform_block& block) const size_t operator()(const internal::transform_block& block) const { return hash_funcs(block); }
{
return XXH3_64bits(block.data(), sizeof(internal::transform_block));
}
}; };
template <> template <>
struct hasher<internal::paired_model_matrix> { struct hasher<internal::paired_model_matrix> {
size_t operator()(const internal::paired_model_matrix& paired_matrix) const 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 <typename Tag>
struct tagged_hasher<internal::paired_model_matrix_ptr_t, Tag> {
size_t operator()(const internal::paired_model_matrix& paired_matrix) const
{
return hash_funcs(paired_matrix.local_to_world);
} }
}; };

21
primitive_process/interface/primitive/simple/cylinder.hpp

@ -6,21 +6,26 @@
namespace internal namespace internal
{ {
struct cylinder_t final : primitive { struct cylinder_t final : public primitive {
void initialize(primitive_data_center_t &) override; void initialize(primitive_data_center_t &) override;
void destroy() override; void destroy() override;
primitive_type get_type() const override { return PRIMITIVE_TYPE_CYLINDER; }; primitive_type get_type() const override { return PRIMITIVE_TYPE_CYLINDER; };
stl_vector_mp<marked_subface_ptr_t<subface>> get_subfaces() const override
{
return {static_pointer_cast<subface>(cylinder_face),
static_pointer_cast<subface>(bottom_plane),
static_pointer_cast<subface>(top_plane)};
}
stl_vector_mp<surface_type> get_subface_types() const override
{
return {surface_type::cylinder, surface_type::plane, surface_type::plane};
}
marked_subface_ptr_t<internal::cylinder_face_t> cylinder_face{}; marked_subface_ptr_t<internal::cylinder_face_t> cylinder_face{};
marked_subface_ptr_t<internal::plane_t> bottom_plane{}; marked_subface_ptr_t<internal::plane_t> bottom_plane{};
marked_subface_ptr_t<internal::plane_t> top_plane{}; marked_subface_ptr_t<internal::plane_t> top_plane{};
protected:
void initialize(primitive_data_center_t &, const std::vector<std::pair<internal::paired_model_matrix *, bool>> &) override;
marked_subface_ptr_t<subface> *get_subface() const override { return (marked_subface_ptr_t<subface> *)(&cylinder_face); }
size_t get_subface_count() const override { return 3; }
}; };
} // namespace internal } // namespace internal

12
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; }; primitive_type get_type() const override { return PRIMITIVE_TYPE_SPHERE; };
marked_subface_ptr_t<internal::sphere_face_t> sphere_face{}; stl_vector_mp<marked_subface_ptr_t<subface>> get_subfaces() const override
{
protected: return {static_pointer_cast<subface>(sphere_face)};
void initialize(primitive_data_center_t &, const std::vector<std::pair<internal::paired_model_matrix *, bool>> &) override; }
marked_subface_ptr_t<subface> *get_subface() const override { return (marked_subface_ptr_t<subface> *)(&sphere_face); } stl_vector_mp<surface_type> get_subface_types() const override { return {surface_type::sphere}; }
size_t get_subface_count() const override { return 1; } marked_subface_ptr_t<internal::sphere_face_t> sphere_face{};
}; };
} // namespace internal } // namespace internal

3
primitive_process/interface/primitive_descriptor.h

@ -13,7 +13,8 @@ typedef enum {
PRIMITIVE_TYPE_BOX, PRIMITIVE_TYPE_BOX,
// PRIMITIVE_TYPE_MESH, // PRIMITIVE_TYPE_MESH,
PRIMITIVE_TYPE_EXTRUDE_POLYLINE, PRIMITIVE_TYPE_EXTRUDE_POLYLINE,
PRIMITIVE_TYPE_EXTRUDE_HELIXLINE PRIMITIVE_TYPE_EXTRUDE_HELIXLINE,
PRIMITIVE_TYPE_MAX_COUNT
} primitive_type; } primitive_type;
// // Placeholder, currently used to represent empty body // // Placeholder, currently used to represent empty body

34
primitive_process/interface/subface/simple/cylinder_face.hpp

@ -22,41 +22,33 @@ struct cylinder_face_t final : subface {
double v) const override; double v) const override;
std::function<equation_intermediate_t(constraint_curve_intermediate &&)> fetch_solver_evaluator() const override; std::function<equation_intermediate_t(constraint_curve_intermediate &&)> fetch_solver_evaluator() const override;
}; };
struct cylinder_paired_model_matrix {
internal::paired_model_matrix *data{};
};
} // namespace internal } // namespace internal
namespace detail namespace detail
{ {
struct cylinder_surface_tag{};
template <> template <>
struct hasher<internal::cylinder_paired_model_matrix> { struct tagged_hasher<internal::paired_model_matrix_ptr_t, cylinder_surface_tag> {
size_t operator()(const internal::cylinder_paired_model_matrix &block) const size_t operator()(const internal::paired_model_matrix& block) const
{ {
const auto& mat = block.data->local_to_world.matrix(); // 3x4 auto R = block.world_to_local.linear().topLeftCorner<2, 3>(); // 2x3
Eigen::Matrix3d A = mat.block<3,3>(0,0); auto b = block.local_to_world.translation(); // 3x1
Eigen::Vector3d b = mat.col(3);
Eigen::Matrix3d B = A.inverse();
Eigen::Matrix<double, 2, 3> 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)); Eigen::Matrix<double, 3, 4> hash_mat = Eigen::Matrix3d::Zero();
h ^= XXH3_64bits(zero_proj.data(), sizeof(Eigen::Vector2d)); hash_mat.topLeftCorner<3, 3>() = R.transpose() * R;
hash_mat.topRightCorner<2, 1>() = R * b;
return h; return hash_funcs(hash_mat);
} }
}; };
template <> template <>
struct default_elem_ctor<internal::cylinder_paired_model_matrix, internal::cylinder_face_t> { struct default_elem_ctor<internal::paired_model_matrix_ptr_t, internal::cylinder_face_t> {
internal::cylinder_face_t operator()(const internal::cylinder_paired_model_matrix &k) const internal::cylinder_face_t operator()(internal::paired_model_matrix& k) const
{ {
internal::cylinder_face_t res{}; internal::cylinder_face_t res{};
res.model_matrices = const_cast<internal::paired_model_matrix *>(k.data); res.model_matrices = make_pointer_wrapper(k);
return res; return res;
} }
}; };

29
primitive_process/interface/subface/simple/plane.hpp

@ -22,32 +22,33 @@ struct plane_t final : subface {
double v) const override; double v) const override;
std::function<equation_intermediate_t(constraint_curve_intermediate &&)> fetch_solver_evaluator() const override; std::function<equation_intermediate_t(constraint_curve_intermediate &&)> fetch_solver_evaluator() const override;
}; };
struct plane_paired_model_matrix {
internal::paired_model_matrix *data{};
};
} // namespace internal } // namespace internal
namespace detail namespace detail
{ {
struct plane_surface_tag {
};
template <> template <>
struct hasher<internal::plane_paired_model_matrix> { struct tagged_hasher<internal::paired_model_matrix_ptr_t, plane_surface_tag> {
size_t operator()(const internal::plane_paired_model_matrix &block) const // 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(); const auto &mat = block.local_to_world.matrix();
Eigen::Matrix<double, 3, 2> character_col; Eigen::Vector3d normal = mat.col(1).cross(mat.col(2)).normalized();
character_col.col(0) = mat.col(0); if (normal.x() < 0 || (normal.x() == 0 && normal.y() < 0) || (normal.x() == 0 && normal.y() == 0 && normal.z() < 0)) {
character_col.col(1) = mat.col(3); normal = -normal;
return XXH3_64bits(character_col.data(), sizeof(Eigen::Matrix<double, 3, 2>)); }
return hash_funcs(normal);
} }
}; };
template <> template <>
struct default_elem_ctor<internal::plane_paired_model_matrix, internal::plane_t> { struct default_elem_ctor<internal::paired_model_matrix_ptr_t, internal::plane_t> {
internal::plane_t operator()(const internal::plane_paired_model_matrix &k) const internal::plane_t operator()(internal::paired_model_matrix_ptr_t &k) const
{ {
internal::plane_t res{}; internal::plane_t res{};
res.model_matrices = const_cast<internal::paired_model_matrix *>(k.data); res.model_matrices = make_pointer_wrapper(k);
return res; return res;
} }
}; };

10
primitive_process/interface/subface/simple/sphere_face.hpp

@ -26,12 +26,16 @@ struct sphere_face_t final : subface {
namespace detail namespace detail
{ {
struct sphere_surface_tag
{
};
template <> template <>
struct default_elem_ctor<internal::paired_model_matrix *, internal::sphere_face_t> { struct default_elem_ctor<internal::paired_model_matrix_ptr_t, internal::sphere_face_t> {
internal::sphere_face_t operator()(const internal::paired_model_matrix *k) const internal::sphere_face_t operator()(internal::paired_model_matrix& k) const
{ {
internal::sphere_face_t res{}; internal::sphere_face_t res{};
res.model_matrices = const_cast<internal::paired_model_matrix *>(k); res.model_matrices = make_pointer_wrapper(k);
return res; return res;
} }
}; };

41
primitive_process/src/base/primitive.cpp

@ -29,10 +29,10 @@
dynamic_bitset_mp<> primitive::judge_sign_by_subface_sign(stl_vector_mp<dynamic_bitset_mp<>> subface_signs) const dynamic_bitset_mp<> primitive::judge_sign_by_subface_sign(stl_vector_mp<dynamic_bitset_mp<>> subface_signs) const
{ {
auto subfaces = get_subface(); auto subfaces = get_subfaces();
dynamic_bitset_mp<> res = subface_signs.front(); 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()) if (!subfaces[i].is_marked())
res |= subface_signs[i]; res |= subface_signs[i];
else else
@ -42,22 +42,13 @@ dynamic_bitset_mp<> primitive::judge_sign_by_subface_sign(stl_vector_mp<dynamic_
return res; return res;
} }
aabb_t primitive::fetch_aabb() const
{
return m_aabb;
}
void primitive::apply_transform(internal::transform_type type, Eigen::Vector4d param) void primitive::apply_transform(internal::transform_type type, Eigen::Vector4d param)
{ {
auto subfaces = get_subface(); auto subfaces = get_subfaces();
auto subface_count = get_subface_count();
stl_vector_mp<internal::paired_model_matrix_ptr_t> new_model_matrices{};
std::vector<std::pair<internal::paired_model_matrix *, bool>> new_model_matrices{}; new_model_matrices.reserve(subfaces.size());
new_model_matrices.reserve(subface_count); for (size_t i = 0; i < subfaces.size(); ++i) { new_model_matrices.emplace_back(subfaces[i]->apply_transform(type, param)); }
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));
}
// aabb // aabb
Eigen::Affine3d affine = Eigen::Affine3d::Identity(); 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); 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<internal::paired_model_matrix_ptr_t> &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);
}
} }

15
primitive_process/src/base/subface.cpp

@ -6,7 +6,7 @@ subface::~subface() noexcept
{ {
if (!data_center) return; 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; } 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(); } Eigen::Matrix3d subface::trans_world_to_local_linear() const { return model_matrices->world_to_local.linear().transpose(); }
std::pair<internal::paired_model_matrix *, bool> 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) { switch (type) {
case internal::transform_type::scale: { case internal::transform_type::scale: {
temp.local_to_world.linear() = param.head<3>().asDiagonal() * temp.local_to_world.linear(); temp.local_to_world.linear() = param.head<3>().asDiagonal() * temp.local_to_world.linear();
@ -38,13 +38,6 @@ std::pair<internal::paired_model_matrix *, bool> subface::apply_transform(intern
default: throw std::invalid_argument("Invalid transform type"); 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); auto [iter, _] = data_center->transform_blocks.acquire(temp);
return {iter.operator->(), reversed}; return make_pointer_wrapper(iter.operator->());
} }

79
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::identity_model_matrix);
this->transform_blocks.acquire(internal::plane_to_z_pos_1_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); 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<uint8_t>(surface_type::plane)].emplace<plane_container_t>();
this->surfaces[static_cast<uint8_t>(surface_type::sphere)].emplace<sphere_container_t>();
this->surfaces[static_cast<uint8_t>(surface_type::cylinder)].emplace<cylinder_container_t>();
} }
primitive_data_center_t::~primitive_data_center_t() noexcept 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); 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>& subface)
{
switch (type) {
case surface_type::plane: {
auto [iter, is_new] = std::get<plane_container_t>(this->surfaces[static_cast<uint8_t>(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<sphere_container_t>(this->surfaces[static_cast<uint8_t>(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<cylinder_container_t>(this->surfaces[static_cast<uint8_t>(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>& subface)
{
switch (type) {
case surface_type::plane:
{
auto model_matrices = subface->model_matrices;
std::get<plane_container_t>(this->surfaces[static_cast<uint8_t>(type)]).release(model_matrices);
release_transform_block(model_matrices);
break;
}
case surface_type::sphere:
{
auto model_matrices = subface->model_matrices;
std::get<sphere_container_t>(this->surfaces[static_cast<uint8_t>(type)]).release(model_matrices);
release_transform_block(model_matrices);
break;
}
case surface_type::cylinder:
{
auto model_matrices = subface->model_matrices;
std::get<cylinder_container_t>(this->surfaces[static_cast<uint8_t>(type)]).release(model_matrices);
release_transform_block(model_matrices);
break;
}
default:
break;
}
}
namespace internal namespace internal
{ {
PE_API primitive* new_primitive(primitive_type type) PE_API primitive* new_primitive(primitive_type type)

98
primitive_process/src/primitive/simple/cylinder.cpp

@ -4,61 +4,59 @@ namespace internal
{ {
void cylinder_t::initialize(primitive_data_center_t &data_center) 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 bottom_plane_mat = data_center.require_transform_block(internal::plane_to_z_model_matrix);
auto [cylinder_iter, __] = data_center.transform_blocks.acquire(internal::identity_model_matrix); auto cylinder_mat = data_center.require_transform_block(internal::identity_model_matrix);
auto [top_plane_iter, ___] = data_center.transform_blocks.acquire(internal::plane_to_z_pos_1_model_matrix); auto top_plane_mat = data_center.require_transform_block(internal::plane_to_z_pos_1_model_matrix);
initialize(data_center, primitive::initialize(data_center, {cylinder_mat, bottom_plane_mat, top_plane_mat});
{std::pair(cylinder_iter.operator->(), false),
std::pair(bottom_plane_iter.operator->(), true),
std::pair(top_plane_iter.operator->(), false)});
} }
void cylinder_t::destroy() void cylinder_t::destroy()
{ {
auto data_center = bottom_plane.get_ptr()->data_center; primitive_data_center_t &data_center = bottom_plane.get_ptr()->data_center;
data_center->planes.release(plane_paired_model_matrix{bottom_plane.get_ptr()->model_matrices});
data_center->planes.release(plane_paired_model_matrix{top_plane.get_ptr()->model_matrices}); data_center.release_surface(surface_type::cylinder, static_pointer_cast<subface>(cylinder_face));
data_center.release_surface(surface_type::plane, static_pointer_cast<subface>(bottom_plane));
data_center.release_surface(surface_type::plane, static_pointer_cast<subface>(top_plane));
} }
void cylinder_t::initialize(primitive_data_center_t &data_center, // void cylinder_t::initialize(primitive_data_center_t &data_center,
const std::vector<std::pair<internal::paired_model_matrix *, bool>> &new_model_matrices) // const std::vector<std::pair<internal::paired_model_matrix *, bool>> &new_model_matrices)
{ // {
std::array<subface *, 3> old_ptrs{cylinder_face.get_ptr(), bottom_plane.get_ptr(), top_plane.get_ptr()}; // std::array<subface *, 3> old_ptrs{cylinder_face.get_ptr(), bottom_plane.get_ptr(), top_plane.get_ptr()};
std::array<paired_model_matrix *, 3> old_model_matrices{nullptr, nullptr, nullptr}; // std::array<paired_model_matrix *, 3> old_model_matrices{nullptr, nullptr, nullptr};
for (size_t i = 0; i < 3; ++i) { // for (size_t i = 0; i < 3; ++i) {
if (old_ptrs[i] != nullptr) old_model_matrices[i] = old_ptrs[i]->model_matrices; // 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}); // 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_ptr(iter.operator->());
cylinder_face.set_mark(new_model_matrices[0].second); // cylinder_face.set_mark(new_model_matrices[0].second);
if (is_new) cylinder_face.get_ptr()->data_center = &data_center; // 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}); // 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_ptr(iter.operator->());
bottom_plane.set_mark(new_model_matrices[1].second); // bottom_plane.set_mark(new_model_matrices[1].second);
if (is_new) bottom_plane.get_ptr()->data_center = &data_center; // 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}); // 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_ptr(iter.operator->());
top_plane.set_mark(new_model_matrices[2].second); // top_plane.set_mark(new_model_matrices[2].second);
if (is_new) top_plane.get_ptr()->data_center = &data_center; // if (is_new) top_plane.get_ptr()->data_center = &data_center;
} // }
// deferred release to avoid acquiring the same just-released subface // // deferred release to avoid acquiring the same just-released subface
{ // {
if (old_ptrs[0] != nullptr) // if (old_ptrs[0] != nullptr)
data_center.cylinders.release(cylinder_paired_model_matrix{old_model_matrices[0]}); // data_center.cylinders.release(cylinder_paired_model_matrix{old_model_matrices[0]});
if (old_ptrs[1] != nullptr) // if (old_ptrs[1] != nullptr)
data_center.planes.release(plane_paired_model_matrix{old_model_matrices[1]}); // data_center.planes.release(plane_paired_model_matrix{old_model_matrices[1]});
if (old_ptrs[2] != nullptr) // if (old_ptrs[2] != nullptr)
data_center.planes.release(plane_paired_model_matrix{old_model_matrices[2]}); // data_center.planes.release(plane_paired_model_matrix{old_model_matrices[2]});
} // }
} // }
} // namespace internal } // namespace internal

33
primitive_process/src/primitive/simple/sphere.cpp

@ -4,29 +4,28 @@ namespace internal
{ {
void sphere_t::initialize(primitive_data_center_t &data_center) void sphere_t::initialize(primitive_data_center_t &data_center)
{ {
auto [iter, _] = data_center.transform_blocks.acquire(internal::identity_model_matrix); primitive::initialize(data_center, {data_center.require_transform_block(internal::identity_model_matrix)});
initialize(data_center, {std::pair(iter.operator->(), false)});
} }
void sphere_t::destroy() void sphere_t::destroy()
{ {
auto data_center = sphere_face.get_ptr()->data_center; primitive_data_center_t& data_center = sphere_face->data_center;
data_center->spheres.release(sphere_face.get_ptr()->model_matrices); data_center.release_surface(surface_type::sphere, static_pointer_cast<subface>(sphere_face));
} }
void sphere_t::initialize(primitive_data_center_t &data_center, // void sphere_t::initialize(primitive_data_center_t &data_center,
const std::vector<std::pair<internal::paired_model_matrix *, bool>> &new_model_matrices) // const std::vector<std::pair<internal::paired_model_matrix *, bool>> &new_model_matrices)
{ // {
auto old_ptr = sphere_face.get_ptr(); // auto old_ptr = sphere_face.get_ptr();
paired_model_matrix *old_model_matrices{nullptr}; // paired_model_matrix *old_model_matrices{nullptr};
if (old_ptr != nullptr) old_model_matrices = old_ptr->model_matrices; // if (old_ptr != nullptr) old_model_matrices = old_ptr->model_matrices;
auto [iter, is_new] = data_center.spheres.acquire(new_model_matrices[0].first); // auto [iter, is_new] = data_center.spheres.acquire(new_model_matrices[0].first);
sphere_face.set_ptr(iter.operator->()); // sphere_face.set_ptr(iter.operator->());
sphere_face.set_mark(new_model_matrices[0].second); // sphere_face.set_mark(new_model_matrices[0].second);
if (is_new) sphere_face.get_ptr()->data_center = &data_center; // if (is_new) sphere_face.get_ptr()->data_center = &data_center;
// deferred release to avoid acquiring the same just-released subface // // deferred release to avoid acquiring the same just-released subface
if (old_ptr != nullptr) data_center.spheres.release(old_model_matrices); // if (old_ptr != nullptr) data_center.spheres.release(old_model_matrices);
} // }
} // namespace internal } // namespace internal

42
primitive_process/src/subface/simple/cylinder_face.cpp

@ -4,8 +4,8 @@ namespace internal
{ {
auto cylinder_face_t::fetch_sdf_evaluator() const -> std::function<double(Eigen::Vector3d)> auto cylinder_face_t::fetch_sdf_evaluator() const -> std::function<double(Eigen::Vector3d)>
{ {
auto functor = [](Eigen::Vector3d p, Eigen::Vector3d local_to_world_scale, const transform_block* _world_to_local) { 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}; 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(); const double len = local_p.head<2>().norm();
if (len > std::numeric_limits<double>::epsilon()) { if (len > std::numeric_limits<double>::epsilon()) {
@ -16,29 +16,29 @@ auto cylinder_face_t::fetch_sdf_evaluator() const -> std::function<double(Eigen:
} }
}; };
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 cylinder_face_t::fetch_sdf_grad_evaluator() const -> std::function<Eigen::Vector3d(Eigen::Vector3d)> auto cylinder_face_t::fetch_sdf_grad_evaluator() const -> std::function<Eigen::Vector3d(Eigen::Vector3d)>
{ {
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) {
Eigen::Vector4d local_p = *_world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; 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(); Eigen::Vector2d normal = local_p.head<2>().normalized();
return trans_world_to_local_linear * Eigen::Vector3d{normal.x(), normal.y(), 0.0}; 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<Eigen::Vector4d(double, double)> auto cylinder_face_t::fetch_point_by_param_evaluator() const -> std::function<Eigen::Vector4d(double, double)>
{ {
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 cos_u = std::cos(u);
const auto sin_u = std::sin(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 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 cos_u = std::cos(u);
const auto sin_u = std::sin(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{}; constraint_curve_intermediate res{};
res.f = *_local_to_world * Eigen::Vector4d(cos_u, v, sin_u, 1.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); res.grad_f = _local_to_world * Eigen::Vector4d(0, 1, 0, 0.0);
return res; 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 auto cylinder_face_t::fetch_curve_constraint_evaluator(parameter_v_t constraint_var_type, double v) const
-> std::function<constraint_curve_intermediate(double)> -> std::function<constraint_curve_intermediate(double)>
{ {
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 cos_u = std::cos(u);
auto sin_u = std::sin(u); auto sin_u = std::sin(u);
constraint_curve_intermediate res{}; constraint_curve_intermediate res{};
res.f = *_local_to_world * Eigen::Vector4d(cos_u, v, sin_u, 1.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); res.grad_f = _local_to_world * Eigen::Vector4d(-sin_u, 0.0, cos_u, 0.0);
return res; 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<equation_intermediate_t(constraint_curve_intermediate&&)> auto cylinder_face_t::fetch_solver_evaluator() const -> std::function<equation_intermediate_t(constraint_curve_intermediate&&)>
{ {
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{}; 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.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 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 } // namespace internal

40
primitive_process/src/subface/simple/plane.cpp

@ -4,70 +4,70 @@ namespace internal
{ {
auto plane_t::fetch_sdf_evaluator() const -> std::function<double(Eigen::Vector3d)> auto plane_t::fetch_sdf_evaluator() const -> std::function<double(Eigen::Vector3d)>
{ {
auto functor = [](Eigen::Vector3d p, Eigen::Vector3d local_to_world_scale, const transform_block* _world_to_local) { 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}; 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 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<Eigen::Vector3d(Eigen::Vector3d)> auto plane_t::fetch_sdf_grad_evaluator() const -> std::function<Eigen::Vector3d(Eigen::Vector3d)>
{ {
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 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<Eigen::Vector4d(double, double)> auto plane_t::fetch_point_by_param_evaluator() const -> std::function<Eigen::Vector4d(double, double)>
{ {
auto functor = [](double u, double v, const transform_block* _local_to_world) { auto functor = [](double u, double v, const transform_block& _local_to_world) {
return *_local_to_world * Eigen::Vector4d(0, u, v, 1.0); 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 auto plane_t::fetch_curve_constraint_evaluator(parameter_u_t constraint_var_type, double u) const
-> std::function<constraint_curve_intermediate(double)> -> std::function<constraint_curve_intermediate(double)>
{ {
auto functor = [&](double v, const transform_block* _local_to_world) { auto functor = [&](double v, const transform_block& _local_to_world) {
constraint_curve_intermediate res{}; constraint_curve_intermediate res{};
res.f = *_local_to_world * Eigen::Vector4d(0, u, v, 1.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); res.grad_f = _local_to_world * Eigen::Vector4d(0, 0, 1, 0.0);
return res; 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 auto plane_t::fetch_curve_constraint_evaluator(parameter_v_t constraint_var_type, double v) const
-> std::function<constraint_curve_intermediate(double)> -> std::function<constraint_curve_intermediate(double)>
{ {
auto functor = [&](double u, const transform_block* _local_to_world) { auto functor = [&](double u, const transform_block& _local_to_world) {
constraint_curve_intermediate res{}; constraint_curve_intermediate res{};
res.f = *_local_to_world * Eigen::Vector4d(0, u, v, 1.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); res.grad_f = _local_to_world * Eigen::Vector4d(0, 1, 0, 0.0);
return res; 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<equation_intermediate_t(constraint_curve_intermediate&&)> auto plane_t::fetch_solver_evaluator() const -> std::function<equation_intermediate_t(constraint_curve_intermediate&&)>
{ {
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{}; 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.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 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 } // namespace internal

42
primitive_process/src/subface/simple/sphere_face.cpp

@ -4,8 +4,8 @@ namespace internal
{ {
auto sphere_face_t::fetch_sdf_evaluator() const -> std::function<double(Eigen::Vector3d)> auto sphere_face_t::fetch_sdf_evaluator() const -> std::function<double(Eigen::Vector3d)>
{ {
auto functor = [](Eigen::Vector3d p, Eigen::Vector3d local_to_world_scale, const transform_block* _world_to_local) { 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}; 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(); const double len = local_p.head<3>().norm();
if (len > std::numeric_limits<double>::epsilon()) { if (len > std::numeric_limits<double>::epsilon()) {
@ -16,31 +16,31 @@ auto sphere_face_t::fetch_sdf_evaluator() const -> std::function<double(Eigen::V
} }
}; };
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 sphere_face_t::fetch_sdf_grad_evaluator() const -> std::function<Eigen::Vector3d(Eigen::Vector3d)> auto sphere_face_t::fetch_sdf_grad_evaluator() const -> std::function<Eigen::Vector3d(Eigen::Vector3d)>
{ {
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) {
Eigen::Vector4d local_p = *_world_to_local * Eigen::Vector4d{p.x(), p.y(), p.z(), 1.0}; 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(); Eigen::Vector3d normal = local_p.head<3>().normalized();
return trans_world_to_local_linear * normal; 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<Eigen::Vector4d(double, double)> auto sphere_face_t::fetch_point_by_param_evaluator() const -> std::function<Eigen::Vector4d(double, double)>
{ {
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 cos_u = std::cos(u);
const auto sin_u = std::sin(u); const auto sin_u = std::sin(u);
const auto cos_v = std::cos(v); const auto cos_v = std::cos(v);
const auto sin_v = std::sin(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 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 cos_u = std::cos(u);
const auto sin_u = std::sin(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 cos_v = std::cos(v);
auto sin_v = std::sin(v); auto sin_v = std::sin(v);
constraint_curve_intermediate res{}; constraint_curve_intermediate res{};
res.f = *_local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.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); res.grad_f = _local_to_world * Eigen::Vector4d(cos_u * -sin_v, cos_v, sin_u * -sin_v, 0.0);
return res; 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 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 cos_v = std::cos(v);
const auto sin_v = std::sin(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 cos_u = std::cos(u);
auto sin_u = std::sin(u); auto sin_u = std::sin(u);
constraint_curve_intermediate res{}; constraint_curve_intermediate res{};
res.f = *_local_to_world * Eigen::Vector4d(cos_u * cos_v, sin_v, sin_u * cos_v, 1.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); res.grad_f = _local_to_world * Eigen::Vector4d(-sin_u * cos_v, 0.0, cos_u * cos_v, 0.0);
return res; 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<equation_intermediate_t(constraint_curve_intermediate&&)> auto sphere_face_t::fetch_solver_evaluator() const -> std::function<equation_intermediate_t(constraint_curve_intermediate&&)>
{ {
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{}; 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.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 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 } // namespace internal

56
shared_module/container/hashed_refcount_hive.hpp

@ -65,6 +65,59 @@ public:
throw std::runtime_error("Pointer not found in refcount map."); throw std::runtime_error("Pointer not found in refcount map.");
} }
protected:
hive<V, Allocator> data{};
// manually calculate hash for the key, so that we do not need to store the key
flat_hash_map<size_t, std::pair<size_t, iterator>> refcount_data_map{};
};
template <typename T, typename Tag>
struct tagged_hasher;
template <typename K, typename V, typename Tag, typename Allocator = std::allocator<V>>
struct tagged_hashed_refcount_hive {
using iterator = typename hive<V, Allocator>::iterator;
public:
std::pair<iterator, bool> acquire(const K& key)
{
size_t hash_key = tagged_hasher<K, Tag>()(key);
auto iter = refcount_data_map.find(hash_key);
if (iter == refcount_data_map.end()) {
auto data_iter = data.emplace(default_elem_ctor<K, V>{}(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<K, Tag>()(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: protected:
hive<V, Allocator> data{}; hive<V, Allocator> data{};
// manually calculate hash for the key, so that we do not need to store the key // manually calculate hash for the key, so that we do not need to store the key
@ -74,3 +127,6 @@ protected:
template <typename K, typename V> template <typename K, typename V>
using hashed_refcount_hive_mp = detail::hashed_refcount_hive<K, V, mi_stl_allocator<V>>; using hashed_refcount_hive_mp = detail::hashed_refcount_hive<K, V, mi_stl_allocator<V>>;
template <typename K, typename V, typename Tag>
using tagged_hashed_refcount_hive_mp = detail::tagged_hashed_refcount_hive<K, V, Tag, mi_stl_allocator<V>>;

67
shared_module/utils/hash_ext.hpp

@ -0,0 +1,67 @@
#pragma once
#include <functional>
#include <math/eigen_alias.hpp>
#include <xxhash.h>
namespace detail
{
template <typename T>
struct float_to_int_type
{
static_assert(std::is_floating_point_v<T>, "T must be a floating point type");
using type = std::conditional_t<sizeof(T) == 4, uint32_t, uint64_t>;
};
static constexpr float float_hash_epsilon = 1e-6f;
}
struct hash_funcs_fn
{
template <typename T, int M, int N>
size_t operator()(const Eigen::Matrix<T, M, N> &mat) const
{
static_assert(M != Eigen::Dynamic && N != Eigen::Dynamic, "only fixed size matrix is supported");
if constexpr (std::is_integral_v<T>)
return XXH3_64bits(mat.data(), sizeof(T) * M * N);
else if constexpr (std::is_floating_point_v<T>)
{
using integral_type = typename detail::float_to_int_type<T>::type;
Eigen::Matrix<integral_type, M, N> int_mat = (mat.array() / static_cast<T>(detail::float_hash_epsilon)).template cast<integral_type>();
return XXH3_64bits(int_mat.data(), sizeof(integral_type) * M * N);
}
else
static_assert([]() { return false; }(), "unsupported type in hash<Eigen::Matrix>");
}
template <typename T, int N>
size_t operator()(const Eigen::Transform<T, N, Eigen::AffineCompact> &trans) const
{
if constexpr (std::is_integral_v<T>)
return XXH3_64bits(trans.data(), sizeof(T) * N * (N + 1));
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>();
return XXH3_64bits(int_mat.data(), sizeof(integral_type) * N * (N + 1));
}
else
static_assert([]() { return false; }(), "unsupported type in hash<Eigen::Matrix>");
}
template <typename T>
size_t operator()(std::reference_wrapper<T> ref) const
{
return size_t(std::addressof(ref.get()));
}
template <typename T>
size_t operator()(std::reference_wrapper<const T> ref) const
{
return size_t(std::addressof(ref.get()));
}
};
static constexpr hash_funcs_fn hash_funcs{};

9
shared_module/utils/marked_ptr.hpp

@ -1,5 +1,6 @@
#pragma once #pragma once
#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;
@ -45,6 +46,14 @@ struct marked_ptr<T, 1> {
operator bool() const { return is_marked(); } operator bool() const { return is_marked(); }
T* operator->() const { return get_ptr(); }
protected: protected:
T* ptr{nullptr}; 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)
{
return marked_ptr<F, bits_to_store>(static_cast<F*>(p.get_ptr()), p.get_mark());
}

40
shared_module/utils/pointer_wrapper.hpp

@ -0,0 +1,40 @@
#pragma once
#include <type_traits>
template <typename T>
struct pointer_wrapper{
static_assert(std::is_object_v<T>, "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<T&&>(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 <typename T>
auto make_pointer_wrapper(T* p) noexcept -> pointer_wrapper<T>
{
return pointer_wrapper<T>(p);
}
template <typename T>
auto make_pointer_wrapper(T& x) noexcept -> pointer_wrapper<T>
{
return pointer_wrapper<T>(x);
}
Loading…
Cancel
Save