A Gentle Introduction to iMesh

iMesh is an interface for working with discrete polygonal/polyhedral meshes. Meshes are composed of sets of entities, such as vertices, edges, faces or volumes, with tags associated with these entities or sets. Below, we’ll go through some of the basics of working with the iMesh interface to query and manipulate mesh data.

“Hello, World!”

To illustrate the most basic usage of iMesh, let’s start with a simple “Hello, world!” script, run from the interactive shell. Since iMesh isn’t a string processing module, we won’t actually print “Hello, world!”, but instead we’ll just load a file and print out how many entities are contained in that file:

>>> from itaps import iBase, iMesh
>>> mesh = iMesh.Mesh()
>>> mesh.load("mesh.vtk")
>>> mesh.getNumOfType(iBase.Type.all)
256

This simple script contains the basic elements that we’ll see in most PyTAPS programs: we import the iBase and iMesh modules, create a Mesh instance, and then do some work with that instance.

Creating Entities

Oftentimes, we’ll also want to create new entities in our mesh. For vertices, this is about what you’d expect: define the coordinates for the vertex (or an array of coordinates to create several vertices at once) and then pass them to createVtx():

>>> from itaps import iBase, iMesh
>>> mesh = iMesh.Mesh()
>>> verts = mesh.createVtx([[0,0,0], [0,0,1], [0,1,1], [0,1,0]])

For higher-dimension entities, like triangles or hexahedra, supply the entity topology (shape) and the appropriate number of lower-dimension entities to createEnt(). In this case, we’re supplying the vertices we just created, though we could just as well supply edges if we had them:

>>> quad, status = mesh.createEnt(iMesh.Topology.quadrilateral, verts)
>>> mesh.getNumOfType(iBase.Type.face)
1

Getting Entity Data

Continuing from above, we now have a few entities that we can examine. First we’ll try getting the adjacent vertices of the quad we just created:

>>> adj = mesh.getEntAdj(quad, iBase.Type.vertex)
>>> (adj == verts).all()
True

Notice that getEntAdj() returns an array of adjacent entities, and as expected, these are exactly the same as the vertex entities we created above.

Note

This behavior depends on the adjacent vertices being returned in the same order as they were when passed into createEnt(). This may vary depending on the underlying iMesh implementation.

We can also get the coordinate data from our adjacent vertices, and we notice that they match up with the coordinates we specified when creating them:

>>> mesh.getVtxCoords(adj)
array([[ 0.,  0.,  0.],
       [ 0.,  0.,  1.],
       [ 0.,  1.,  1.],
       [ 0.,  1.,  0.]])

Furthermore, we can get an array of all the entities in our mesh using getEntities(). If we preferred, we could have restricted this based on the type (dimension) and/or topology (shape) of the entities. To confirm that we have the entities we expect, we can check their dimension and notice that we have four 0-dimensional entities and one 2-dimensional entity:

>>> ents = mesh.getEntities()
>>> mesh.getEntType(ents)
array([0, 0, 0, 0, 2], dtype=int32)

Note

We’ll return to getEntities() in Working With Sets and Tags and see what’s really happening with this method.

Working With Arrays

Many iMesh functions accept either single values for arguments or arrays of values. In general, the same function is used in both cases; we’ve already seen this work with createVtx() above. However, this would be ambigious with createEnt(), so the array form is a separate function, createEntArr():

>>> from itaps import iBase, iMesh
>>> mesh = iMesh.Mesh()
>>> coords = []
>>> for i in range(10):
...     coords += [[i,0,0], [i,0,1], [i,1,1], [i,1,0]]
...
>>> verts = mesh.createVtx(coords)
>>> quads, status = mesh.createEntArr(iMesh.Topology.quadrilateral, verts)
>>> len(quads)
10

When using getEntAdj() above, you may have noticed that we passed in a single entity and got back an array of entities. Then what happens if we pass in an array of entities? Does it return an array of arrays? Well, not quite. In fact, when called with an array of entities as input, getEntAdj() returns an OffsetListSingle instance.

Offset lists are jagged 2-dimensional arrays implemented as a 1-D array of data and an array of offsets into that data. However, most of the time we can just treat these as jagged arrays:

>>> adj = mesh.getEntAdj(quads, iBase.Type.vertex)
>>> for i in adj:
...     print mesh.getVtxCoords(i).tolist()
...
[[0.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 1.0], [0.0, 1.0, 0.0]]
[[1.0, 0.0, 0.0], [1.0, 0.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 0.0]]
[[2.0, 0.0, 0.0], [2.0, 0.0, 1.0], [2.0, 1.0, 1.0], [2.0, 1.0, 0.0]]
[[3.0, 0.0, 0.0], [3.0, 0.0, 1.0], [3.0, 1.0, 1.0], [3.0, 1.0, 0.0]]
[[4.0, 0.0, 0.0], [4.0, 0.0, 1.0], [4.0, 1.0, 1.0], [4.0, 1.0, 0.0]]
[[5.0, 0.0, 0.0], [5.0, 0.0, 1.0], [5.0, 1.0, 1.0], [5.0, 1.0, 0.0]]
[[6.0, 0.0, 0.0], [6.0, 0.0, 1.0], [6.0, 1.0, 1.0], [6.0, 1.0, 0.0]]
[[7.0, 0.0, 0.0], [7.0, 0.0, 1.0], [7.0, 1.0, 1.0], [7.0, 1.0, 0.0]]
[[8.0, 0.0, 0.0], [8.0, 0.0, 1.0], [8.0, 1.0, 1.0], [8.0, 1.0, 0.0]]
[[9.0, 0.0, 0.0], [9.0, 0.0, 1.0], [9.0, 1.0, 1.0], [9.0, 1.0, 0.0]]

Sets and Tags

To learn about how to work with sets and tags, continue on to Working With Sets and Tags.

Table Of Contents

Previous topic

Why Use PyTAPS

Next topic

A Gentle Introduction to iGeom

This Page