3 Mechanical Models I

3.7 Mesh components

ArtiSynth models frequently incorporate 3D mesh geometry, as defined by the geometry classes PolygonalMesh, PolylineMesh, and PointMesh described in Section 2.5. Within a model, these basic classes are typically enclosed within container components that are subclasses of MeshComponent. Commonly used instances of these include

RigidMeshComp

Introduced in Section 3.2.9, these contain the mesh geometry for rigid bodies, and are stored in a rigid body subcomponent list named meshes. Their mesh vertex positions are fixed with respect to their body’s coordinate frame.

FemMeshComp

Contain mesh geometry associated with finite element models (Chapter 6), including surfaces meshes and embedded mesh geometry, and are stored in a subcomponent list of the FEM model named meshes. Their mesh vertex positions change as the FEM model deforms.

SkinMeshBody

Described in detail in Chapter 10, these describe “skin” geometry that encloses both rigid bodies and/or FEM models. Their mesh vertex positions change as the underlying bodies move and deform. Skinning meshes may be placed anywhere, but are typically stored in the meshBodies component list of a MechModel.

FixedMeshBody

Described further below, these store arbitrary mesh geometry (polygonal, polyline, and point) and provide (like rigid bodies) a rigid coordinate frame that allows the mesh to be positioned and oriented arbitrarily. As their name suggests, their mesh vertex positions are fixed with respect to this coordinate frame. Fixed body meshes may be placed anywhere, but are typically stored in the meshBodies component list of a MechModel.

3.7.1 Fixed mesh bodies

As mentioned above, FixedMeshBody can be used for placing arbitrary mesh geometry within an ArtiSynth model. These mesh bodies are non-dynamic: they do not interact or collide with other model components, and they function primarily as 3D graphical objects. They can be created from primary mesh components using constructors such as:

FixedMeshBody (MeshBase mesh)

Create an unnamed body containing a specified mesh.

FixedMeshBody (String name, MeshBase mesh)

Create a named body containing a specified mesh.

It should be noted that the primary meshes are not copied and are instead stored by reference, and so any subsequent changes to them will be reflected in the mesh body. As with rigid bodies, fixed mesh bodies contain a coordinate frame, or pose, that describes the position and orientation of the body with respect to world coordinates. Methods to control the pose include:

RigidTransform3d getPose()

Returns the pose of the body (with respect to world).

void setPose (RigidTransform3d XFrameToWorld)

Sets the pose of the body.

@VERTSPACE[0.5em]
Point3d getPosition()

Returns the body position (pose translation component).

void setPosition (Point3d pos)

Sets the body position.

@VERTSPACE[0.5em]
AxisAngle getOrientation()

Returns the body orientation (pose rotation component).

void setOrientation (AxisAngle axisAng)

Sets the body orientation.

Once created, a canonical place for storing mesh bodies is the MechModel component list meshBodies. Methods for maintaining this list include:

ComponentListView<MeshComponent> meshBodies()

Returns the meshBodies list.

void addMeshBody (MeshComponent mcomp)

Adds mcomp to meshBodies.

boolean removeMeshBody (MeshComponent mcomp)

Removes mcomp from meshBodies.

void clearMeshBodies()

Clears the meshBodies list.

Meshes used for instantiating fixed mesh bodies are typically read from files (Section 2.5.5), but can also be created using factory methods (Section 2.5.1). As an example, the following code fragment creates a torus mesh using a factory method, set its pose, and then adds it to a MechModel:

   MechModel mech;
   ...
   PolygonalMesh mesh = MeshFactory.createTorus (
      /*rmajor=*/1.0, /*rminor=*/0.2, /*nmajor=*/32, /*nminor=*/10);
   FixedMeshBody mbody = new FixedMeshBody ("torus", mesh);
   mbody.setPose (
      new RigidTransform3d (/*xyz=*/0,0,0, /*rpy=*/0,0,Math.toRadians(90)));
   mech.addMeshBody (mbody);

Rendering of mesh bodies is controlled using the same properties described in Section 3.2.8 for rigid bodies, including the renderProps subproperties faceColor, shading, alpha, faceStyle, and drawEdges, and the properties axisLength and axisDrawStyle for displaying a body’s coordinate frame.

3.7.2 Example: adding mesh bodies to MechModel

Figure 3.32: FixedMeshes model loaded into ArtiSynth.

An simple application that creates a pair of fixed meshes and adds them to a MechModel is defined in

  artisynth.demos.tutorial.FixedMeshes

The build() method for this is shown below:

1    public void build (String[] args) {
2       // create a MechModel to add the mesh bodies to
3       MechModel mech = new MechModel ("mech");
4       addModel (mech);
5
6       // read torus mesh from a file stored in the folder "data" located under
7       // the source folder of this model:
8       String filepath = getSourceRelativePath ("data/torus_9_24.obj");
9       PolygonalMesh mesh = null;
10       try {
11          mesh = new PolygonalMesh (filepath);
12       }
13       catch (Exception e) {
14          System.out.println ("Error reading file " + filepath + ": " + e);
15          return;
16       }
17       // create a FixedMeshBody containing the mesh and add it to the MechModel
18       FixedMeshBody torus = new FixedMeshBody ("torus", mesh);
19       mech.addMeshBody (torus);
20
21       // create a square mesh with a factory method and add it to the MechModel
22       mesh = MeshFactory.createRectangle (
23          /*width=*/3.0, /*width=*/3.0, /*ndivsx=*/10, /*ndivsy=*/10,
24          /*addTextureCoords=*/false);
25       FixedMeshBody square = new FixedMeshBody ("square", mesh);
26       mech.addMeshBody (square);
27       // reposition the square: translate it along y and rotate it about x
28       square.setPose (
29          new RigidTransform3d (/*xyz=*/0,0.5,0,/*rpy=*/0,0,Math.toRadians(90)));
30
31       // set rendering properties:
32       // make torus pale green
33       RenderProps.setFaceColor (torus, new Color (0.8f, 1f, 0.8f));
34       // show square coordinate frame using solid arrows
35       square.setAxisLength (0.75);
36       square.setAxisDrawStyle (AxisDrawStyle.ARROW);
37       // make square blue gray with mesh edges visible
38       RenderProps.setFaceColor (square, new Color (0.8f, 0.8f, 1f));
39       RenderProps.setDrawEdges (square, true);
40       RenderProps.setEdgeColor (square, new Color (0.5f, 0.5f, 1f));
41       RenderProps.setFaceStyle (square, FaceStyle.FRONT_AND_BACK);
42    }

After creating a MechModel (lines 3-4), a torus shaped mesh is imported from the file data/torus_9_24.obj (lines 8-16). As described in Section 2.6, the RootModel method getSourceRelativePath() is used to locate this file relative to the model’s source folder. The file path is used in the PolygonalMesh constructor, which is enclosed within a try/catch block to handle possible I/O exceptions. Once imported, the mesh is used to instantiate a FixedMeshBody named "torus" which is added to the MechModel (lines 18-19).

Another mesh, representing a square, is created with a factory method and used to instantiate a mesh body named "square" (lines 22-26). The factory method specifies both the size and triangle density of the mesh in the x-y plane. Once created, the square’s pose is set to a 90 degree rotation about the x axis and a translation of 0.5 along y (lines 28-29).

Rendering properties are set at lines 33-41. The torus is made pale green by setting it face color; the coordinate frame for the square is made visible as solid arrows using the axisLength and axisDrawStyle properties; and the square is made blue gray, with its edges made visible and drawn using a darker color, and its face style set to FRONT_AND_BACK so that it’s visible from either side.

To run this example in ArtiSynth, select All demos > tutorial > FixedMeshes from the Models menu. The model should load and initially appear as in Figure 3.32.