[BUG FIX] Apply MeshSet poses to sampled particles. - #3171
Conversation
| particles_i, | ||
| np.asarray(morph_i.pos, dtype=gs.np_float), | ||
| np.asarray(morph_i.quat, dtype=gs.np_float), | ||
| ) |
There was a problem hiding this comment.
The transform is mathematically correct, but please compute pos_i and quat_i once and use the same values for both the particles and self._vmesh[i] in this loop, then remove the later visual-transform loop. This avoids maintaining two derivations of the same member pose and keeps particle placement, rendering, and skinning in the same frame.
These are validated internal tuples, so the repository guidelines also require np.array rather than np.asarray.
pos_i = np.array(morph_i.pos, dtype=gs.np_float)
quat_i = np.array(morph_i.quat, dtype=gs.np_float)
particles.append(gu.transform_by_trans_quat(particles_i, pos_i, quat_i))
self._vmesh[i].apply_transform(gu.trans_quat_to_T(pos_i, quat_i))|
|
||
|
|
||
| @pytest.mark.required | ||
| def test_mesh_set_particle_transform(show_viewer): |
There was a problem hiding this comment.
CODING_GUIDELINES.md sections 12.1–12.2 require bug-fix regression assertions to be added to the existing test covering the capability; bug fixes are explicitly not an exception.
Please fold this MeshSet entity and its assertions into an existing MPM test and reuse that scene build. A separate test incurs another full Genesis initialization for every CI configuration.
|
|
||
| @pytest.mark.required | ||
| def test_mesh_set_particle_transform(show_viewer): | ||
| pos = np.array((0.2, 0.1, 0.2)) |
There was a problem hiding this comment.
Please keep this value as a tuple:
pos = (0.2, 0.1, 0.2)The scene-construction guidelines prohibit wrapping controlled array-like inputs in np.array, and the project assertion helper accepts tuples directly.
| mpm_options=gs.options.MPMOptions( | ||
| lower_bound=(-0.5, -0.5, -0.5), | ||
| upper_bound=(0.5, 0.5, 0.5), | ||
| particle_size=0.01, |
There was a problem hiding this comment.
Keyword arguments must follow the callee's declaration order, so particle_size must precede lower_bound and upper_bound.
The custom bounds are also unnecessary for this geometry because it already fits inside the default MPM domain. This can be reduced to:
mpm_options=gs.options.MPMOptions(
particle_size=0.01,
),| poss=(pos,), | ||
| eulers=((0.0, 0.0, 90.0),), | ||
| ), | ||
| material=gs.materials.MPM.Elastic(sampler="regular"), |
There was a problem hiding this comment.
Scene-building calls require one option per line, even when only one option is provided:
material=gs.materials.MPM.Elastic(
sampler="regular",
),| ) | ||
|
|
||
| particles = entity.init_particles | ||
| np.testing.assert_allclose(particles.mean(axis=0), pos, atol=1e-6) |
There was a problem hiding this comment.
Please use the repository assertion utility instead of NumPy's testing API:
from ..utils.assertions import assert_allcloseThen call assert_allclose(..., atol=1e-6).
An explicit atol=1e-6 sits at roughly 5x the measured fp32 floor (~2e-7) while still detecting the 0.08 failure by five orders of magnitude, and stays a fixed absolute bound across precision arms.
|
|
||
| particles = entity.init_particles | ||
| np.testing.assert_allclose(particles.mean(axis=0), pos, atol=1e-6) | ||
| np.testing.assert_allclose(np.ptp(particles, axis=0), (0.11, 0.03, 0.03), atol=1e-6) |
There was a problem hiding this comment.
This catches a completely missing rotation, but it does not fully validate MeshSet pose semantics.
A single centered box cannot detect applying the wrong member's pose, and +90° and −90° rotations have identical means and extents. Please test at least two members with different rotation axes and make one mesh off-center or assert another direction-sensitive quantity so an inverse rotation fails.
Please also derive the expected spans from extents - particle_size and consider asserting that the particle and public visual-mesh AABBs remain aligned.
Note this interacts with the bounds comment above: keep every member inside the default MPM domain (z well above 0, within the safety padding), or the custom bounds become necessary again.
|
Hi @prexhu, just following up on this draft. Are you planning to continue addressing the review feedback? I’d be happy to help with the implementation or test restructuring if useful. |
Description
Apply each MeshSet member's rotation and translation to its sampled particle positions.
Previously, MeshSet particles were only translated, while the corresponding visual mesh received the complete pose.
Add an MPM regression test using an asymmetric mesh rotated by 90 degrees.
Related Issue
Resolves #3169
Motivation and Context
Hybrid entities instantiate their soft parts through MeshSet. Ignoring each member's rotation caused particles generated from rotated URDF links to remain aligned with the original local axes instead of attaching to the links.
How Has This Been / Can This Be Tested?
Screenshots (if appropriate):
Checklist:
Submitting Code Changessection of CONTRIBUTING document.