Rest shape measure#229
Conversation
…ipc-toolkit into rest_shape_measure
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #229 +/- ##
==========================================
- Coverage 95.84% 95.78% -0.06%
==========================================
Files 160 160
Lines 16611 16686 +75
Branches 923 937 +14
==========================================
+ Hits 15921 15983 +62
- Misses 690 703 +13
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds an option to use rest-shape (non-differentiated) quadrature measures for smooth-contact primitives to avoid spurious gradients from integrating over deformed collision mesh parameters.
Changes:
- Introduces
use_rest_shape_measureinSmoothContactParametersto toggle rest-shape quadrature weights. - Updates Point2/Point3/Edge2/Edge3 to use rest-shape length/area weights and to drop derivative contributions from the measure when enabled.
- Refactors Face primitive evaluation to return rest-shape area (and zero derivatives) when enabled.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| src/ipc/smooth_contact/common.hpp | Adds use_rest_shape_measure toggle to parameters. |
| src/ipc/smooth_contact/primitives/point3.hpp | Stores a cached rest-shape quadrature weight for Point3. |
| src/ipc/smooth_contact/primitives/point3.cpp | Computes/uses rest-shape Point3 weight; removes measure derivatives when enabled. |
| src/ipc/smooth_contact/primitives/point2.hpp | Stores a cached rest-shape length measure for Point2. |
| src/ipc/smooth_contact/primitives/point2.cpp | Passes a “measure” into point2 terms and switches between rest/deformed measures. |
| src/ipc/smooth_contact/primitives/face.hpp | Changes Face evaluation API to instance methods and stores rest area. |
| src/ipc/smooth_contact/primitives/face.cpp | Computes rest area; returns constant measure / zero derivatives when enabled. |
| src/ipc/smooth_contact/primitives/edge3.hpp | Stores cached rest-shape squared edge length. |
| src/ipc/smooth_contact/primitives/edge3.cpp | Uses rest/deformed squared-length weight and drops its derivatives when enabled. |
| src/ipc/smooth_contact/primitives/edge2.hpp | Stores cached rest-shape edge length. |
| src/ipc/smooth_contact/primitives/edge2.cpp | Returns rest length / zero derivatives when enabled. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -99,6 +99,8 @@ struct SmoothContactParameters { | |||
| double beta_n = 0; | |||
| int r = 2; | |||
|
|
|||
| if (m_params.use_rest_shape_measure) { | ||
| // Rest-shape vertex area measure: sum of squared rest 1-ring edge | ||
| // lengths / 3 Constant quadrature weight per the paper (Eq. 13), never | ||
| // differentiated through | ||
| const Eigen::MatrixXd& rp = mesh.rest_positions(); | ||
| m_rest_weight = 0.0; | ||
| for (int a = 0; a < edges.rows(); a++) { | ||
| const Eigen::RowVector3d t = | ||
| rp.row(local_to_global_vids[edges(a, 1)]) | ||
| - rp.row(local_to_global_vids[edges(a, 0)]); | ||
| m_rest_weight += t.squaredNorm(); | ||
| } | ||
| m_rest_weight /= 3.0; | ||
| } |
| double Face::potential( | ||
| Eigen::ConstRef<Eigen::Vector3d> d, Eigen::ConstRef<Vector9d> x) const |
| Vector12d Face::grad( | ||
| Eigen::ConstRef<Eigen::Vector3d> d, Eigen::ConstRef<Vector9d> x) const |
| Matrix12d Face::hessian( | ||
| Eigen::ConstRef<Eigen::Vector3d> d, Eigen::ConstRef<Vector9d> x) const |
| const double measure = m_params.use_rest_shape_measure | ||
| ? m_rest_measure | ||
| : ((x.segment<DIM>(DIM) - x.segment<DIM>(0)).norm() | ||
| + (x.segment<DIM>(2 * DIM) - x.segment<DIM>(0)).norm()) | ||
| / 2.0; |
| const T measure = m_params.use_rest_shape_measure | ||
| ? T(m_rest_measure) | ||
| : ((X.row(2) - X.row(1)).norm() + (X.row(3) - X.row(1)).norm()) | ||
| / 2.0; |
| const T measure = m_params.use_rest_shape_measure | ||
| ? T(m_rest_measure) | ||
| : ((X.row(2) - X.row(1)).norm() + (X.row(3) - X.row(1)).norm()) | ||
| / 2.0; |
Description
For all the primitives, using quadrature on the rest shape instead of on the autodiff/differentiable parameters of the collision mesh. This feature is enabled by adding a use_rest_shape_measure parameter in SmoothParams
Fixes # (issue)
Type of change
How Has This Been Tested?
This was necessary for a 2D GCP case where spurious gradients appear when integrating on the deformation coordinates.
However, no explicit testing was done, except gradient visualization
Checklist