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. 38
      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. 58
      shared_module/container/hashed_refcount_hive.hpp
  22. 67
      shared_module/utils/hash_ext.hpp
  23. 11
      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);
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<uint32_t>(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 {

3
network_process/src/prim_gen/extract_vertex_infos.cpp

@ -1,8 +1,5 @@
#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)
{
primitive_boundings.reserve(tree.primitives.size());

16
primitive_process/interface/base/primitive.hpp

@ -13,6 +13,7 @@
template <typename T>
using marked_subface_ptr_t = marked_ptr<T, 1>;
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 };
@ -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<subface> *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<marked_subface_ptr_t<subface>> get_subfaces() const = 0;
virtual stl_vector_mp<surface_type> get_subface_types() const = 0;
// 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;
dynamic_bitset_mp<> judge_sign_by_subface_sign(stl_vector_mp<dynamic_bitset_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<std::pair<internal::paired_model_matrix *, bool>> &) = 0;
void initialize(primitive_data_center_t &, const stl_vector_mp<internal::paired_model_matrix_ptr_t> &);
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 &&)>
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<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/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 {
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
hashed_refcount_hive_mp<internal::plane_paired_model_matrix, internal::plane_t> planes{};
hashed_refcount_hive_mp<internal::paired_model_matrix*, internal::sphere_face_t> spheres{};
hashed_refcount_hive_mp<internal::cylinder_paired_model_matrix, internal::cylinder_face_t> cylinders{};
using surface_containers = std::variant<plane_container_t, sphere_container_t, cylinder_container_t>;
std::array<surface_containers, static_cast<uint8_t>(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>& 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

26
primitive_process/interface/data/data_type.hpp

@ -1,9 +1,9 @@
#pragma once
#include <xxhash.h>
#include <math/eigen_alias.hpp>
#include <container/hashed_refcount_hive.hpp>
#include <utils/hash_ext.hpp>
#include <utils/pointer_wrapper.hpp>
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<paired_model_matrix>;
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<primitive_data_center_t>;
enum class surface_type : uint8_t { plane, sphere, cylinder, cone, max_count };
namespace detail
{
template <>
struct hasher<internal::transform_block> {
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<internal::paired_model_matrix> {
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
{
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<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::plane_t> bottom_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

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; };
marked_subface_ptr_t<internal::sphere_face_t> sphere_face{};
protected:
void initialize(primitive_data_center_t &, const std::vector<std::pair<internal::paired_model_matrix *, bool>> &) override;
stl_vector_mp<marked_subface_ptr_t<subface>> get_subfaces() const override
{
return {static_pointer_cast<subface>(sphere_face)};
}
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

3
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

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

@ -22,41 +22,33 @@ struct cylinder_face_t final : subface {
double v) 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 detail
{
struct cylinder_surface_tag{};
template <>
struct hasher<internal::cylinder_paired_model_matrix> {
size_t operator()(const internal::cylinder_paired_model_matrix &block) const
struct tagged_hasher<internal::paired_model_matrix_ptr_t, cylinder_surface_tag> {
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<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));
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<double, 3, 4> 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_paired_model_matrix, internal::cylinder_face_t> {
internal::cylinder_face_t operator()(const internal::cylinder_paired_model_matrix &k) const
struct default_elem_ctor<internal::paired_model_matrix_ptr_t, internal::cylinder_face_t> {
internal::cylinder_face_t operator()(internal::paired_model_matrix& k) const
{
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;
}
};

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

@ -22,32 +22,33 @@ struct plane_t final : subface {
double v) 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 detail
{
struct plane_surface_tag {
};
template <>
struct hasher<internal::plane_paired_model_matrix> {
size_t operator()(const internal::plane_paired_model_matrix &block) const
struct tagged_hasher<internal::paired_model_matrix_ptr_t, plane_surface_tag> {
// 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<double, 3, 2> 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<double, 3, 2>));
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_paired_model_matrix, internal::plane_t> {
internal::plane_t operator()(const internal::plane_paired_model_matrix &k) const
struct default_elem_ctor<internal::paired_model_matrix_ptr_t, internal::plane_t> {
internal::plane_t operator()(internal::paired_model_matrix_ptr_t &k) const
{
internal::plane_t res{};
res.model_matrices = const_cast<internal::paired_model_matrix *>(k.data);
res.model_matrices = make_pointer_wrapper(k);
return res;
}
};

10
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::paired_model_matrix *, internal::sphere_face_t> {
internal::sphere_face_t operator()(const internal::paired_model_matrix *k) const
struct default_elem_ctor<internal::paired_model_matrix_ptr_t, internal::sphere_face_t> {
internal::sphere_face_t operator()(internal::paired_model_matrix& k) const
{
internal::sphere_face_t res{};
res.model_matrices = const_cast<internal::paired_model_matrix *>(k);
res.model_matrices = make_pointer_wrapper(k);
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
{
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<dynamic_
return res;
}
aabb_t primitive::fetch_aabb() const
{
return m_aabb;
}
void primitive::apply_transform(internal::transform_type type, Eigen::Vector4d param)
{
auto subfaces = get_subface();
auto subface_count = get_subface_count();
std::vector<std::pair<internal::paired_model_matrix *, bool>> 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<internal::paired_model_matrix_ptr_t> 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<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;
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<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) {
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<internal::paired_model_matrix *, bool> 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->());
}

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::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<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
@ -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>& 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
{
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)
{
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<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,
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<paired_model_matrix *, 3> 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<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<paired_model_matrix *, 3> 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

33
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<subface>(sphere_face));
}
void sphere_t::initialize(primitive_data_center_t &data_center,
const std::vector<std::pair<internal::paired_model_matrix *, bool>> &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<std::pair<internal::paired_model_matrix *, bool>> &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

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

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

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

58
shared_module/container/hashed_refcount_hive.hpp

@ -65,6 +65,59 @@ public:
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:
hive<V, Allocator> 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 <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{};

11
shared_module/utils/marked_ptr.hpp

@ -1,5 +1,6 @@
#pragma once
#include <cstddef>
template <typename T, size_t bits_to_store>
struct marked_ptr {
static constexpr size_t mask = (1 << bits_to_store) - 1;
@ -45,6 +46,14 @@ struct marked_ptr<T, 1> {
operator bool() const { return is_marked(); }
T* operator->() const { return get_ptr(); }
protected:
T* ptr{nullptr};
};
};
template <typename F, typename T, size_t bits_to_store>
inline static marked_ptr<F, bits_to_store> static_pointer_cast(const marked_ptr<T, bits_to_store>& p)
{
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