In addition to controlling the positions of mesh vertices, a SkinMeshBody can also be used to control the positions of dynamic point components, including markers and other points which can be attached to the skin body. For both markers and attached points, any applied forces are propagated back onto the skin body’s master bodies, using the principle of virtual work. This allows skin bodies to be fully incorporated into a dynamic model.
Markers and point attachments can be created even if the SkinMeshBody does not have a mesh, a fact that can be used in situations where a mesh is unnecessary, such as when employing skinning techniques for muscle wrapping (Section 8.7).
Markers attached to a skin body are instances of SkinMarker, and are contained in the body’s subcomponent list markers (analogous to the markers list for FEM models). Markers can be created and maintained using the following SkinMeshBody methods:
The addMarker methods each create and return a SkinMarker which is added to the skin body’s list of markers. The marker’s initial position is specified by pos, while the second and third methods also allow a name to be specified. Connections between the marker and the master bodies are created in the same way as for mesh vertices, with the connection weights either being determined by the skin body’s weighting function (as returned by getWeightingFunction()), or explicitly specified by the argument weights (third method).
Once created, markers can be removed individually or all together by the removeMarker() and clearMarkers() methods. The entire marker list can be accessed on a read-only basis by the method markers().
In addition to markers, applications can also attach any regular Point component (including particles and FEM nodes) to a skin body by using one of its createPointAttachment methods:
Both of these create a PointSkinAttachment that connects the point pnt to the master bodies in the same way as for mesh vertices and markers, with the connection weights either being determined by the skin body’s weighting function or explicitly specified by the argument weights in the second method.
Once created, the point attachment must also be added to the underlying MechModel, as illustrated by the following code fragment:
An example of skinning a mesh over both rigid bodies and FEM models is
given by the demo model
artisynth.demos.tutorial.AllBodySkinning. It consists of a skin mesh placed around a tubular FEM model connected to rigid bodies connected at each end, and a marker attached to the mesh tip. The code for the build() method is given below:
A MechModel is first created and length and density parameters are defined (lines 2-8). Then a tubular FEM model is created, by using the FemFactory method createHexTube() and transforming the result by rotating it by 90 degrees about the axis (lines 10-14). Two rigid body blocks are then created (lines 16-26) and attached to the ends of the FEM model by finding and attaching the left and rightmost nodes (lines 28-24). The model is anchored to ground by setting the left block to be non-dynamic (line 21).
The mesh to be skinned is a rounded cylinder, created using the MeshFactory method createRoundedCylinder() and rotating the result by 90 degrees about the axis (lines 39-44). This is then used to create the skin body itself, to which both rigid bodies and the FEM model are added as master bodies and the vertex connections are computed using a call to computeAllVertexConnections() (lines 46-52). A marker is then added to the tip of the skin body, using the addMarker() method (lines 54-56). Finally render properties are set (lines 58-64): The mesh is made transparent by drawing only its edges in cyan; the FEM model surface mesh is rendered in blue-grey, and the tip marker is drawn as a red sphere.
To run this example in ArtiSynth, select All demos > tutorial > AllBodySkinning from the Models menu. The model should load and initially appear as in Figure 8.4 (left). When running the simulation, the FEM and the rightmost rigid body fall under gravity, causing the skin mesh to deform. The pull tool can then be used to move things around by applying forces to the master bodies or the skin mesh itself.
For the markers and point attachments described above, the connections to the underlying master bodies are created in the same manner as connections for individual mesh vertices. This means that the resulting markers and attached points move independently of the mesh vertices, as though they were vertices in their own right.
An advantage to this is that such markers and attachments can be created even if the SkinMeshBody does not even have a mesh, as noted above. However, a disadvantage is that such markers will not remain tightly connected to vertex-based features (such as the faces of a PolygonalMesh or the line segments of a PolylineMesh). For example, consider a marker defined by
where pos is a point that is initially located on a face of the body’s mesh. As the master bodies move and the mesh deforms, the resulting marker may not remain strictly on the face. In many cases, this may not be problematic or the deviation may be too small to matter. However, if it is desirable for markers or point attachments to be tightly bound to mesh features, they can instead be created with the following methods:
The requested position pos will then be projected onto the nearest mesh feature (e.g., a face for a PolygonalMesh or a line segment for a PolylineMesh), and the resulting position will be defined as a linear combination of the vertex positions for this feature,
where are the barycentric coordinates of with respect to the feature. The master body connections are then defined by the same linear combination of the connections for each vertex. When the master bodies move, the marker or attached point will move with the feature and remain in the same relative position.
Since SkinMeshBody implements the interface PointAttachable, it provides the general point attachment method
which allows it to be acted on by agents such as the ArtiSynth marker tool (see the section “Marker tool” in the ArtiSynth User Interface Guide). Whether or not the resulting attachment is a regular attachment or mesh-based is controlled by the skin body’s attachPointsToMesh property, which can be adjusted in the GUI or in code using the property’s accessor methods: