LiPrimitiveTriangulate

FunctionLtStatus
LiPrimitiveTriangulate( LtPrim prim
LtTriangulate method
)
Synopsis Triangulate a single primitive using the triangulation method specified.
Locationligeops
Parameters
prim The primitive to be triangulated.
method The triangulation method to be used.
Return Value An indication of success, failure or error.

Description The function will triangulate the given primitive, using the specified triangulation method.

LiPrimitiveTriangulate is accompanied by an execution method, LI_EXECUTE_TRIANGULATE, which will call LiPrimitiveTriangulate for every primitive on the active primitive list, using the LI_TRIANGULATE_DEFAULT triangulation method.

LiPrimitiveTriangulate will repeatedly call a simple "triangulate this polygon" routine, with every polygon of the given primitive. Only primitives of type LI_PRIM_TYPE_POLY and LI_PRIM_TYPE_MESH will be processed by this routine. Passing in a primitive of any other type, will result in a non-zero return value.

The LtTriangulate parameter specifies the particular triangulation method that the caller wishes to see employed. The LightWorks ADS supports 4 different triangulation methods. These are outlined in the table, below.

All names should be prefixed LI_TRIANGULATE_
Name Comment
SIMPLE Keep meshing until all polygons have been triangulated
MAX_EDGE_LENGTH Keep meshing until all polygons have been triangulated
and no edge in the mesh is longer than some
caller-defined maximum edge length.
POLY_COUNT Keep meshing until all polygons have been triangulated
and the total number of triangles is at least the
caller-defined minimum number.
DEFAULT One of the above; the user can change what the default
triangulation method is for an entire scene, and
for a particular primitive, or collection of primitives.

When a primitive is passed to LiPrimitiveTriangulate, any primitive-specific meshing requirements (defined by a meshing refinement, attached to the primitive) will be utilised. A meshing refinement can also be set as the global default ... to apply in the absence of any primitive-specific information. This default refinement is set and read via the control variable LI_CONTROL_MESHING_REFINEMENT , whose type is an LtMeshingRefinement , and whose default value is NULL.

Meshing refinements, and meshing criteria, are vital to any explanation of how LiPrimitiveTriangulate behaves. When this documentation refers to a primitive's `relevant LI_MESH_CRIT_NAME value', the reader should bear in mind the following 3-step operation, used whenever a value is being sought for any criterion

  • If the primitive being triangulated has a meshing refinement attached, and the criterion under consideration has been set for this refinement, then this value will be used by the triangulation code.
  • If there is no refinement attached, or the relevant criterion has not been set on the refinement that is attached, then the code will look for a non-NULL global refinement ( LI_CONTROL_MESHING_REFINEMENT). If such a global refinement is found and it has had the relevant criterion set, then the value stored with this global meshing refinement is utilised.
  • Otherwise, the system default value will be used.

    Having established that it is dealing with a polygon, or polymesh, primitive, the first action of LiPrimitiveTriangulate is to establish what triangulation method it is being asked to employ. When called with any method other than LI_TRIANGULATE_DEFAULT, this choice is simple; the code will employ the specified method (the LtTriangulate parameter).

    When called with LI_TRIANGULATE_DEFAULT, the code will use the primitive's relevant LI_MESH_CRIT_METHOD value

    Regardless of which triangulation method is decided upon ( SIMPLE, POLY_COUNT, or MAX_EDGE_LENGTH) the next action of LiPrimitiveTriangulate is to decide whether it is triangulating the polygons of the primitive as they stand, or whether extra vertices should first be added.

    When the primitive's relevant LI_MESH_CRIT_MAX_EDGE_VERTS value is TRUE, each (non-bridge) polygon edge has its length compared to the maximum edge length defined by the primitive's relevant LI_MESH_CRIT_MAX_EDGE_LENGTH value. If the polygon edge is longer than the prescribed maximum length, then the polygon edge is split up into enough equal-sized pieces to ensure that all the pieces satisfy the length criterion. Once this process has been repeated for all edges of the primitive, the resulting polygons are simply triangulated.

    If the primitive's relevant LI_MESH_CRIT_MAX_EDGE_VERTS value is FALSE, then no edge splitting takes place before the core triangulation operation.

    Once the core triangulation has been successfully completed, LiPrimitiveTriangulate will examine the primitive's relevant LI_MESH_CRIT_EDGE_SWAPPING value, to see if an optimal triangulation is being sought by the caller, or merely an acceptable one.

    If the relevant LI_MESH_CRIT_EDGE_SWAPPING value is equal to LI_EDGE_SWAP_NONE, then no change will be made to the triangle mesh which has just been generated. However, if this value is LI_EDGE_SWAP_ALL, then all internal edges of the primitive are examined, to establish if any of them form the diagonal of a flat, convex quadrilateral. Those that do are tested to see if splitting the quadrilateral along its other diagonal might not produce a better triangulation (i.e., one with a bigger minimum internal angle). If such a swap appears to improve things, then the edge is swapped. At the end of such a sweep, the mesh is a Constrained Delaunay Triangulation.

    If the relevant LI_MESH_CRIT_EDGE_SWAPPING value is LI_EDGE_SWAP_NEW, then only those internal edges which are created during the current call to LiPrimitiveTriangulate will be considered for swapping. This will preserve the boundaries of those polygons which were passed into the routine, allowing the caller to build a hierarchical triangulation, should they so wish, by making repeated calls with varying meshing parameters.

    At the end of an LI_EDGE_SWAP_NEW sweep of all polygon edges, a Constrained Delaunay Triangulation will again result, but it will likely have more constraints than the triangulation which would have resulted from an LI_EDGE_SWAP_ALL sweep of the same polygons.

    Having carried out (or not) edge swapping, to the satisfaction of the relevant LI_MESH_CRIT_EDGE_SWAPPING value, LiPrimitiveTriangulate will examine the triangulation method that is being employed, to see if any further work needs to be done:

    • If the method being employed is LI_TRIANGULATE_SIMPLE, then the routine will now quit.
    • If the method being employed is LI_TRIANGULATE_POLY_COUNT, then the code will repeat the following loop, until the number of triangles in the mesh is at least as large as the relevant LI_MESH_CRIT_POLY_COUNT value:
      • find the primitive's longest polygon edge, and split it into 2 equal-length pieces;
      • re-triangulate the 1 or 2 faces which share the recently-split edge;
      • ensure that the relevant LI_MESH_CRIT_EDGE_SWAPPING value is satisfied.

        Having raised the polygon count to the requisite level, the routine will quit. \item If the method being employed is LI_TRIANGULATE_MAX_EDGE_LENGTH, then the code will repeat the same 3-step loop, until every polygon edge is no longer than the primitive's relevant LI_MESH_CRIT_MAX_EDGE_LENGTH value. Having succeeded in disposing of all edges which are too long, the routine will quit. \end{itemize}

Example
/*
 * triangulate.  Ensure result is Constrained
 * Delaunay Triangulation
 */
data = LiDataCreate();
ref = LiMeshingRefinementCreate();
LiDataSetEnum(data, LI_EDGE_SWAP_ALL);
LiMeshingRefinementSetCriterion(ref, 
                                LI_MESH_CRIT_EDGE_SWAPPING, 
                                data)
LiDataSetGenericPtr(data, ref);
LiControlSet( LI_CONTROL_MESHING_REFINEMENT, data);
LiPrimitiveTriangulate(prim, LI_TRIANGULATE_SIMPLE);
See Also LiPrimitiveHierarchicalTriangulate
LiPrimitiveSetMeshingRefinement
LiMeshingTriProperties
LiMeshingEdgeSwap
LiMeshingEdgeSplit
LiMeshingInsertBridge

Copyright © 1990-1998, 1999 LightWork Design Limited. All rights reserved