27. AGX Util
AGXUtil is a namespace that is part of the agxPhysics shared library. AGX Util provides different utility functions and classes.
27.1. Jump Request
The method agxUtil::jumpRequest provides a way to move a collection
of items, including wires, that are part of an agxSDK::Assembly.
/**
This method will perform a "jump request" will all bodies in the assembly,
including bodies which are part of wires. parentBody is the main body
which will work as a parent, all other bodies will move relative to this
rigid body.
The transform parentBodyWorldTransform defines the new transform for
the parent body, the target transform for parentBody.
Also, make sure parentBody is part of the assembly collection
\param collection - An Assembly which contain all bodies (including parentBody) and wires.
\param parentBody - The main rigid body, all other bodies will move relative to this body
\param parentBodyWorldTransform - The new requested transformation for the parentBody.
\param wireOptions - options how to handle wire nodes
\return the number of bodies that where moved, including parentBody
*/
size_t jumpRequest( agxSDK::Assembly* collection,
agx::RigidBody* parentBody,
const agx::AffineMatrix4x4& parentBodyWorldTransform,
agx::UInt32 wireOptions = agx::UInt32( 0 ) );
The wireOptions allows for specifying how wire nodes should be handled
when the node parent is not part of the collection:
Contact nodes can be detached and turned into lumped nodes instead.
Eye nodes can be changed into lumped nodes.
When this method executes, the items in collection will be updated.
27.2. Sphere-Mesh Skeletonisation
Under the agxUtil namespace lies the helper function agxUtil::skeletoniseMesh:
/**
Utilises the SphereSkeletoniser class to generate a SphereSkeleton from a given
trimesh structure.
\param vertices The vertices of the mesh
\param indices The indices of the mesh (always 3 per triangle, see agxCollide/Trimesh.h)
*/
SphereSkeleton skeletoniseMesh(const agx::Vec3Vector& vertices,
const agx::UInt32Vector& indices);
and a class agxUtil::SphereSkeletoniser which both allow using a trimesh to generate a skeleton of a mesh.
This skeleton can then be traversed directly or processed using additional methods. It can be segmented using
agxUtil::SphereSkeleton::segmentSkeleton or be processed to produce the longest path using
agxUtil::getLongestContinousPath.
The main intended use of these functions are to aid the
the creation of routes for agxCable and agxWire instances and an example of this can be seen in example_mesh_to_cable.cpp
(here seen simplified):
auto cable = new agxCable::Cable(radius, resolution);
for (SphereSkeleton::dfs_iterator it = skeleton.begin(); !it.isEnd(); ++it)
cable->add(new agxCable::FreeNode(it->position));
simulation->add(cable);
The quality of the skeletons produced relies heavily on the quality of the input mesh and as such
it is recommended to use meshes with evenly distributed vertices along the meshes surface and to
use simple shapes for the best results. Other meshes still produce results but some experimentation
using the parameters available in agxUtil::SphereSkeletoniser, post-processing by hand, or using the
processing functions may be necessary.
Note
AGX uses Assimp for importing meshes and by default allows splitting vertices for both normals and UV-coordinates. This behaviour can create non-manifold meshes so to ensure this doesn’t affect the skeletonisation, we advise to use the REMOVE_DUPLICATE_VERTICES flag when importing meshes for this purpose.