For essential background information on the mesh construction history, please read this document before proceeding.
A modifier is the basic atomic unit for all geometry and operations that affect geometry. If you wish to implement a new primitive, or if you wish to implement any change to any mesh, including attribute modifications, you must use a modifier. Collectively, modifiers implement the non-linear mesh construction history for a mesh. A modifier is a node. As such you can store a modifier anywhere in the hierarchy although modifiers function only when placed as a child of a mesh node.
Modifiers are always implemented in C++.
When implementing a modifier you can expect to engage in the following types of operations:
Scenome uses a winged-edge mesh, also called a connected mesh, to implement mesh geometry. Unlike a non-connected mesh, the winged-edge data structure contains additional information about how the faces, edges, and vertices in a mesh relate to each other. Prior experience with winged-edge meshes is helpful but not required. A basic understanding of the concept of a winged-edge mesh is required if you wish to write effective modifiers.
Internally, Scenome's mesh uses triangles exclusively. However an edge can hide to produce a mesh of quadrilaterals - though the mesh is still composed of triangles. Whether or not an edge is "hidden" or "visible" can affect the geometric result of modifiers such as BevelModifier. As you learn about connected mesh topology you will become more familiar with these rules.
The last significantly important concept is traversal of a mesh in what is termed "connected mesh space". Connected mesh space is a term that refers to the mesh data structure topology regardless of the 3D presentation of the mesh. Modifiers rely heavily on traversing mesh geometry in connected mesh space. For example you might implement a modifier that starts with a face-set, finds the edge-set for the face-set, and then performs a specific operation on those edges. You might also more literally traverse the mesh by following a face to its connected faces and so forth. This is fairly routine but you should be aware of the difference between a topologically finite and a topologically infinite mesh. A rectangle sheet is topologically finite because when you traverse the connected mesh geometry you eventually reach an 'end' where there are no additional traversals. On the other hand, a cube is topologically infinite and you can in theory forever traverse the geometry therein.
Scenome's class library includes many helpful functions with respect to connected meshes and these are often very useful during the process of implementing a modifier.
A great many modifiers rely on clever implementations of very basic operations such as edge collapse, edge split, edge turn, and so forth. In general all operations on a connected mesh are actually performed on edges. Sometimes you will need to write a modifier that actually creates new geometry - as with a polygon extrude. You can write modifiers that work in "3d space" if necessary but this greatly increases the complexity of a modifier. The concept of connected mesh space is very important because it separates the 3d presentation of a mesh from its inherent geometry.
A modifier has two basic effects on a mesh; a modifier implements a deep refinement or a shallow refinement. A shallow refinement simply changes the mesh or mesh attributes but in such a way that the actual edge count is not altered. Turning an edge is an example of a shallow refinement; the edge count is neither increased nor decreased, although the topology of the mesh is altered. Splitting or collapsing an edge are examples of deep refinements. Generally any operation that requires re-indexing of the mesh is considered a deep refinement. A shallow refinement typically only affects the attributes such as vertex color, vertex u/v, or vertex position. Transforming a face, edge, or vertex really amounts to transforming vertices and is not a deep refinement. Similarly, altering the node parameters for a mesh is not a deep refinement.
Modifiers that implement deep refinements tend to have complex order-of-operations requirements in the algorithms that implement the modifier. This is because it is possible to introduce paradoxes. Conceptually it is important to develop algorithms that are only "forward thinking" in their design, or simply stated, algorithms that only consider the current state of the mesh and do not in any way rely on the prior state of the mesh. This is because the construction history does not and cannot in any way guarantee that geometry will exist. While there are methods for handling these paradoxes, they often cause performance problems.
Last, it is of course vastly easier to write modifiers if you use non-linear cost algorithms. Sometimes this is unavoidable and sometimes it's avoidable but results in a longer implementation. Modifiers are worth the investment of time required to implement algorithms with linear cost.