Browse Source

refactor(cylinder_face): use geometric hash based on world_to_local transform

Instead of relying on object identity or raw transform parameters, the hasher
now uses intrinsic geometric properties to determine cylinder equivalence.

The hash is computed from:
- G = R^T * R  : encodes the cylinder's cross-sectional metric and axis direction
- v = R * d    : encodes the axial offset in the radial plane

where R is the top-left 2x3 submatrix of the world_to_local linear part,
and d is its translation vector. This ensures that two cylinder faces
with the same shape, orientation, and central axis (even if parameterized
differently) produce the same hash.
V2-origin
mckay 1 week ago
parent
commit
b04bfcf403
  1. 16
      primitive_process/interface/subface/simple/cylinder_face.hpp

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

@ -34,8 +34,20 @@ template <>
struct hasher<internal::cylinder_paired_model_matrix> { struct hasher<internal::cylinder_paired_model_matrix> {
size_t operator()(const internal::cylinder_paired_model_matrix &block) const size_t operator()(const internal::cylinder_paired_model_matrix &block) const
{ {
Eigen::Matrix<double, 2, 4> character_rows = block.data->local_to_world.matrix().topRows<2>(); const auto& mat = block.data->local_to_world.matrix(); // 3x4
return XXH3_64bits(character_rows.data(), sizeof(decltype(character_rows))); 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;
} }
}; };

Loading…
Cancel
Save