LiPrimitiveHierarchicalTriangulate

FunctionLtStatus
LiPrimitiveHierarchicalTriangulate( LtPrim prim
LtGref meshrefs
)
Synopsis Repeatedly call LiPrimitiveTriangulate, with the same primitive, attaching a different meshing refinement for each call.
Locationligeops
Parameters
prim The primitive to be triangulated.
meshrefs A linked list of meshing refinements.
Return Value An indication of success, failure or error.

Description Consider the following scenario: An advanced user calls LiPrimitiveTriangulate to achieve a "maximum edge length" triangulation, and then calls it again, straight away, to achieve a "polygon count" triangulation. The problem here is that LiPrimitiveTriangulate will create edge adjacency information at the beginning of the first call, maintain the data through the first triangulation, and destroy it when done. At the start of the second call, this data will have to be re-created; a somewhat expensive process for complex meshes.

For users that wish to make multiple consecutive calls to LiPrimitiveTriangulate, for each primitive, this destroy/re-create overhead will surely become expensive, for large scenes. LiPrimitiveHierarchicalTriangulate is provided to avoid the high cost of such calls.

LiPrimitiveHierarchicalTriangulate takes a single primitive, and a linked list of meshing refinements ( LtMeshingRefinement). Its behaviour is outlined in the following enumerated list:

  • store any meshing refinement that is attached to the primitive;
  • attach the first meshing refinement, from the list, to the primitive;
  • tell LiPrimitiveTriangulate that it should create edge adjacency information, but not destroy it;
  • call LiPrimitiveTriangulate with the primitive, and the LI_TRIANGULATE_DEFAULT) triangulation method;
  • tell LiPrimitiveTriangulate that is should re-use the edge adjacency data that is has just preserved;
  • attach the next meshing refinement, from the list, to the primitive;
  • call LiPrimitiveTriangulate with the primitive, and the LI_TRIANGULATE_DEFAULT) triangulation method.

    Steps 6 and 7 are repeated until the last meshing refinement is reached, at which point LiPrimitiveHierarchicalTriangulate will:

    • tell LiPrimitiveTriangulate that it should destroy its edge adjacency info, as soon as it is finished with it;
    • attach the last refinement from the list, to the primitive;
    • call LiPrimitiveTriangulate with the primitive, and the LI_TRIANGULATE_DEFAULT triangulation method;
    • tell LiPrimitiveTriangulate that it should revert back to create/destroy behaviour for its edge adjacency information.
    • re-attach the meshing refinement that was originally attached to the primitive, if any;

      N.B., The "first meshing refinement" is the one that is pointed to by "meshrefs->next". This is because a generic reference is always assumed to point at the LAST list element. Care must be taken to ensure this convention is observed, by the caller.

      The function's return value is equal to the return values of the various calls to LiPrimitiveTriangulate, bitwise OR-ed together. (Unless something like invalid input was encountered, and we never got as far as triangulating anything).

      Invalid input to LiPrimitiveHierarchicalTriangulate includes:

      • a NULL primitive
      • a NULL list of refinements
      • a list of refinements containing less than 2 entries (the user should simply attach the refinement themselves, and call LiPrimitiveTriangulate, in this case).

        Caveat

        One problem with the approach just described, is that edge swapping may be overly restricted when using LI_EDGE_SWAP_NEW. This setting allows us to swap any edges created during the current call to LiPrimitiveTriangulate, but not any of those which were extant when the call was made. If LiPrimitiveHierarchicalTriangulate is going to call LiPrimitiveTriangulate many times, where does it draw the line on what are new edges, and what were extant at the time of "the" call?

        We introduce LI_MESH_CRIT_RESET_EDGES. This is an LtMeshingCriterion which expects an LtBoolean value. This criterion is completely ignored, unless LiPrimitiveTriangulate is being called from LiPrimitiveHierarchicalTriangulate. Even then, the value is ignored for the first such call. Otherwise, it allows us to specify whether the edges which are extant as we enter LiPrimitiveTriangulate (for the 2nd, 3rd, ... times) should count as extant edges, or not. The default value is TRUE, and this means that edges present as we enter cannot be swapped, if LI_EDGE_SWAP_NEW is in effect. If set to FALSE, then we refer back to the last call where LI_MESH_CRIT_RESET_EDGES was TRUE.

        For example, if we call LiPrimitiveHierarchicalTriangulate with a list of 6 meshing refinements, and the values of LI_MESH_CRIT_RESET_EDGES are irrelevant, F, T, F, T, F, and LI_MESH_CRIT_EDGE_SWAPPING is always LI_EDGE_SWAP_NEW, then the code will behave as follows:

        • 1st call: Only edges created during this call can be swapped
        • 2nd call: Only edges created during the 1st call and this call, can be swapped
        • 3rd call: Only edges created during this call can be swapped
        • 4th call: Only edges created during the 3rd call and this call, can be swapped
        • 5th call: Only edges created during this call can be swapped
        • 6th call: Only edges created during the 5th call and this call, can be swapped

          Such functionality may prove useful when building a hierarchy of triangles, where the odd calls are "polygon count" triangulations and the even calls are "max edge length" triangulations.

          Users should be aware that this meshing criterion will NOT function as described when used in conjunction with " LI_MESH_CRIT_MAX_EDGE_VERTS~=~TRUE". Such a setting will always result in the edges being reset. This criterion is anyway meant for the initial call, not subsequent calls. It will tend to hinder, rather than help, the generation of quality triangulations when used in later calls.

Example
gref = LiGenericReferenceCreate((LtGenericPtr)meshref1);
gref2 = LiGenericReferenceCreate((LtGenericPtr)meshref2);
gref = LiGenericReferenceAppend(gref, gref2);
gref3 = LiGenericReferenceCreate((LtGenericPtr)meshref3);
gref = LiGenericReferenceAppend(gref, gref3);
gref4 = LiGenericReferenceCreate((LtGenericPtr)meshref4);
gref = LiGenericReferenceAppend(gref, gref4);

status = 
   LiPrimitiveHierarchicalTriangulate(prim, 
                                      gref);
See Also LiPrimitiveTriangulate
LiPrimitiveSetMeshingRefinement
LiMeshingTriProperties
LiMeshingEdgeSwap
LiMeshingEdgeSplit
LiMeshingInsertBridge

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