- Change pattern eval_sdf to return double (signed distance) instead of pair
- Add reversed parameter to get_local_cap_mat for correct cap orientation
- Add has_end_caps flag to extrude, handle closed axis caps properly
- Add is_closed field to polyline_axis_descriptor
- Use desc.is_closed instead of computing from point/bulge counts
- Fix total_theta calculation in helixline (multiply by two_pi)
- Fix scale vector initialization (zero-fill w component)
rewrite confirm of signs when requiring planes, now we do not need any explicit input of signs;
fix the error when using even resolution as bg mesh resolution;
add simple primitive cone and box
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.
Note: Cylinder's side surface defines its AABB, and z-axis scaling does not affect its radius.
Degeneracy checks only consider x/y directions (first two rows of the transform matrix), since z scaling does not change the essential geometry.
TODO: Consider redefining cylinder so the identity transform is always the first subface.