Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slightly confusing documentation for CollisionMesh #29

Closed
Andlon opened this issue Mar 17, 2023 · 4 comments · Fixed by #31
Closed

Slightly confusing documentation for CollisionMesh #29

Andlon opened this issue Mar 17, 2023 · 4 comments · Fixed by #31
Assignees
Labels
documentation Improvements or additions to documentation enhancement New feature or request

Comments

@Andlon
Copy link

Andlon commented Mar 17, 2023

Following #27, I realized that there is one thing that has caused me more confusion than anything else. I understand the purpose of CollisionMesh, however some terminology is not quite clear to me.

For example, the CollisionConstraints::compute_potential_hessian method says:

...
@param[in] vertices Vertices of the collision mesh.
...
@returns The hessian of all barrier potentials (not scaled by the barrier stiffness). This will have a size of |vertices|x|vertices|.

This refers to vertices of the collision mesh. It's not quite clear to me if this generally refers to the "full mesh vertices" or the "surface mesh vertices". From some preliminary testing with CollisionMesh::build_from_full_mesh, it looks like it computes the Hessian with respect to the "full" mesh, is this correct? (Also, should that perhaps be 3|vertices| x 3 |vertices|, or something like that?)

However, in one of the CollisionMesh constructor, it also says:

@brief Construct a new Collision Mesh object directly from the collision mesh vertices.

So this sounds as if the collision mesh vertices here is something entirely different from the full mesh vertices, i.e. as opposed to full mesh vertices. Or perhaps, in this case, the full mesh vertices and the collision mesh vertices are anyway the same?

In short, the exact meaning of "vertices of the collision mesh" / "collision mesh vertices", as used throughout the library (perhaps in slightly different forms), is not entirely clear to me.

As I spend more time playing around with the library and through experimentation, what is expected and returned from various methods starts to become clearer, but for new users in particular I can imagine that this might be a source of confusion.

@Andlon Andlon added the bug Something isn't working label Mar 17, 2023
@Andlon
Copy link
Author

Andlon commented Mar 17, 2023

I couldn't label this as documentation and ended up with bug. Perhaps it should have been enhancement, as it's not really a bug!

@zfergus zfergus added documentation Improvements or additions to documentation enhancement New feature or request and removed bug Something isn't working labels Mar 17, 2023
@zfergus
Copy link
Member

zfergus commented Mar 17, 2023

Thanks again for pointing this out.

CollisionMesh::build_from_full_mesh takes the full (volumetric) mesh vertices and surface edges/faces which index into the full mesh vertices. It then builds a selection matrix to go from full to surface vertices and maps the edge/faces entries accordingly.

CollisionConstraints::compute_potential_hessian returns a matrix of size vertices.size()xvertices.size() (vertices.size() = vertices.rows() * vertices.cols()). Where vertices are the CollisionMesh's vertices (i.e., just the surface vertices if you are working with a volumetric mesh).

If you then want the Hessian in terms of the full (volumetric) mesh that was used to build the collision mesh there is the function:

/// @brief Map a matrix quantity on the collision mesh to the full mesh.
/// This is useful for mapping Hessians from the collision mesh to the full
/// mesh (i.e., applies the chain-rule).
/// @param X Matrix quantity on the collision mesh with size equal to ndof() × ndof().
/// @return Matrix quantity on the full mesh with size equal to full_ndof() × full_ndof().
Eigen::SparseMatrix<double> CollisionMesh::to_full_dof(const Eigen::SparseMatrix<double>& X) const;

This handles applying the chain rule of going from full to surface vertices (i.e., multiplying by the transpose of the selection matrix).

Hopefully, this answers your questions.

P.s. I was thinking I will finally add a basic example in the docs of all this (like #5 asked for). Hopefully, that will help new users get started. In the meantime don't hesitate to reach out with any other questions.

@zfergus
Copy link
Member

zfergus commented Mar 17, 2023

One other thing: in all the code the DOF that derivatives are taken with respect to are the vertices flattened row-wise. That is, for vertices

v0x v0y v0z
v1x v1y v1z
     ⋮

you will get the derivatives in the order

v0x
v0y
v0z
v1x
v1y
v1z
 ⋮

@Andlon
Copy link
Author

Andlon commented Mar 17, 2023

Thanks @zfergus, that really helps clear things up! I think that might just have saved me from some headaches later :-)

@zfergus zfergus mentioned this issue Mar 18, 2023
@zfergus zfergus linked a pull request Mar 18, 2023 that will close this issue
@zfergus zfergus closed this as completed Mar 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants