PK_TOPOL_facet_mesh_o_t   


struct PK_TOPOL_facet_mesh_o_s
    {
    int                o_t_version;      --- version of this PK option struct
    PK_facet_shape_t   shape;            --- constraints on facet generation
                                         --- (PK_facet_shape_convex_c)
    PK_facet_match_t   match;            --- vertex matching strategy at edges
                                         --- (PK_facet_match_topol_c)
    PK_facet_density_t density;          --- increased facet silhouette density
                                         --- (PK_facet_density_no_view_c)
    PK_facet_cull_t    cull;             --- culling of view dependent facets
                                         --- (PK_facet_cull_none_c)
    int                n_loops;          --- array of loops in sheet bodies to
    PK_LOOP_t         *loops;            --- be ignored when facetting(0,NULL)
    int                max_facet_sides;  --- max number of sides on a facet (3)
    PK_LOGICAL_t    is_min_facet_width;  --- whether min_facet_width is set
                                         --- (PK_LOGICAL_false)
    double             min_facet_width;  --- minimum facet width
    PK_LOGICAL_t    is_max_facet_width;  --- whether max_facet_width is set
                                         --- (PK_LOGICAL_false)
    double             max_facet_width;  --- maximum facet width
    PK_LOGICAL_t    is_curve_chord_tol;  --- whether curve_chord_tol is set
                                         --- (PK_LOGICAL_false)
    double             curve_chord_tol;  --- chordal tolerance between a curve
                                         --- and its facet edges in model units
                                         --- i.e. upper bound on distance from
                                         --- chord to the curve it approximates
    PK_LOGICAL_t    is_curve_chord_max;  --- whether curve_chord_max is set
                                         --- (PK_LOGICAL_false)
    double             curve_chord_max;  --- max length of chord in model units
                                         --- i.e upper bound on length of chord
                                         ---  used to approximate a curved edge
    PK_LOGICAL_t    is_curve_chord_ang;  --- whether curve_chord_ang is set
                                         --- (PK_LOGICAL_false)
    double             curve_chord_ang;  --- max angle between curve and chord
                                         --- used to approximate it, in radians
                                         --- i.e. upper bound on sum of angles
                                         ---  between chord and curve tangents
                                         ---  measured at the chord ends.
    PK_LOGICAL_t    is_surface_plane_tol;--- whether surface_plane_tol is set
                                         --- (PK_LOGICAL_false)
    double             surface_plane_tol;--- distance tolerance between surface
                                         ---      and its facet, in model units
                                         --- i.e upper bound on distance from a
                                         --- position on a facet to the surface
    PK_LOGICAL_t    is_surface_plane_ang;--- whether surface_plane_ang is set
                                         --- (PK_LOGICAL_false)
    double             surface_plane_ang;--- angular tolerance between surface
                                         ---      and its facet, in radians.
                                         --- i.e upper bound on the angular
                                         --- deviation between surface normals
                                         --- at any 2 positions under the facet
    PK_LOGICAL_t    is_facet_plane_tol;  --- whether facet_plane_tol is set
                                         --- (PK_LOGICAL_false)
    double             facet_plane_tol;  --- max dist from facet to mid-plane
                                         --- (defined : passing through C of G)
                                         --- (of facet vertices in a direction)
                                         --- (given by averaged vertex normals)
    PK_LOGICAL_t    is_facet_plane_ang;  --- whether facet_plane_ang is set
                                         --- (PK_LOGICAL_false)
    double             facet_plane_ang;  --- facet_plane_tol : max_facet_width
                                         --- (max permitted ratio between them)
    PK_LOGICAL_t   is_local_density_tol; --- whether local_density_tol is set
                                         --- (PK_LOGICAL_false)
    double            local_density_tol; --- local value of surface_plane_tol
                                         --- (for facet silhouette density)
    PK_LOGICAL_t   is_local_density_ang; --- whether local_density_ang is set
                                         --- (PK_LOGICAL_false)
    double            local_density_ang; --- local value of surface_plane_ang
                                         --- (for facet silhouette density)
    PK_facet_degen_t   degen;            --- whether to output multiple
                                         --- vertices at degeneracies and
                                         --- how the singular parameter at the
                                         --- degeneracy is calculated
                                         --- (PK_facet_degen_multiple_vxs_c)
    int         n_view_directions;       --- array of view directions in which
    PK_VECTOR1_t                         --- to increased the facet density
               *view_directions;         --- (0, NULL)
    int         n_local_tols;            --- array of sets of local tolerances
    PK_facet_local_tolerances_t
               *local_tols;              --- (0, NULL)
    int         n_topols_with_local_tols;--- array of topological entities for
    PK_TOPOL_t *topols_with_local_tols;  --- for which local tolerances are
                                         --- specified (0, NULL)
    int        *local_tols_for_topols;   --- index into local_tols
                                         --- picking out the local tolerances
                                         --- to be attached to the
                                         --- corresponding entity in
                                         --- topols_with_local_tols
    PK_facet_ignore_t  ignore;           --- whether to ignore small features
                                         --- when facetting.  Small features
                                         --- can be ignored by inputting an
                                         --- absolute value or a ratio value
                                         --- (PK_facet_ignore_no_c)
    double             ignore_value;     --- features smaller than this will be
                                         --- considered for ignoring (0.0)
    PK_facet_ignore_scope_t
                       ignore_scope;     --- whether to treat a face
                                         --- individually or as part of the
                                         --- face's owning body when looking
                                         --- for ignorable features and
                                         --- facetting a list of faces
                                         --- (PK_facet_ignore_scope_global_c)
    PK_facet_wire_edges_t  wire_edges;   --- whether to take wire edges into
                                         --- account faces when facetting
                                         --- (PK_facet_wire_edges_no_c)
    };
typedef struct PK_TOPOL_facet_mesh_o_s PK_TOPOL_facet_mesh_o_t;



Facet mesh generation controls


Specific Errors:
    PK_ERROR_nitems_lt_0            negative number of items in loop array
    PK_ERROR_lt_3_sides             max_facet_sides too small
    PK_ERROR_distance_too_small     min/max_facet_width too small
    PK_ERROR_distance_too_large     min/max_facet_width too large
    PK_ERROR_bad_tolerance          is_<tol> is true but used with a bad <tol>
                                    or negative number supplied as for local
                                    tolerance
    PK_ERROR_unsuitable_topology    entity is not face or body in
                                    topols_with_local_tols array
    PK_ERROR_bad_value              integer value in local_tols_for_topols
                                    array does not lie between 0 and
                                    n_local_tols


The PK_TOPOL_facet_mesh_o_t structure provides the following controls :

  - facet constraints (i.e. whether holes are permitted in facets or
                            if the generated facets may be concave).
  - which edge matching strategy to use when matching adjacent facetted faces
  - specifying view dependent options (face culling and silhouette density)
  - capping specified loops within a sheet body
  - setting tolerance values to be used in the facetted approximation


Setting tolerance values

The tolerance values are defined by pair of PK_LOGICAL_t and double values,
the former indicating whether the double value has been set explicitly.
PK uses the convention that if no explicit tolerance value is provided,
Parasolid is free to calculate its own internal tolerance values. These
are generally case specific, rather than using specific fixed values.

Defining a viewing matrix

  A number of the mesh options require a viewing matrix to be specified.
  Parasolid has a number of requirements on such matrices.

  In general a viewing matrix shall be of the form M
      | R(11)  R(12)  R(13)  Px |
      |                         |
  M = | R(21)  R(22)  R(23)  Py |
      |                         |
      | R(31)  R(32)  R(33)  Pz |
      |                         |
      | Tx     Ty     Tz     S  |

  The vector T represents a translation
  The vector P represents perspective
  S is the inverse global scale vector
  The rotation submatrix R defines an orthonormal set of vectors H, V, D
      | Hx  Vx  Dx  |
  R = | Hy  Vy  Dy  |
      | Hz  Vz  Dz  |

  M must satisfy the following constraints:

  (i)   The rotation matrix R must be orthonormal
  (ii)  The determinant on R is +1
  (iii) D and P must be parallel if P is not a zero vector
  (iv)  S = 1 - Tz * w (where w = -( D DOT P )


SHAPE
  This field controls whether generated facets can contain holes
  or concave interior angles. The possible settings are one of :

  PK_facet_shape_any_c    : allow creation of holed or concave facets
  PK_facet_shape_cut_c    : cut facets with holes into concave facets
  PK_facet_shape_convex_c : divide concave facets into convex facets  (default)

     ---------------          ---------------            ---------------
    |               |        |               |          |     |         |
    |     /\        |        |     /\        |          |     /\        |
    |    /  \       |        |    /  \       |          |    /  \       |
    |   /    \      |        |   /    \      |          |   /    \      |
    |  /______\     |        |__/______\_____|          |__/______\_____|
    |               |        |               |          |               |
    |_______________|        |_______________|          |_______________|

  PK_facet_shape_any_c     PK_facet_shape_cut_c       PK_facet_shape_convex_c
  --------------------     --------------------       -----------------------

  The diagram above illustrates a (contrived) example of a facet containing an
  interior hole which can be generated using the PK_facet_shape_any_c option.

  The constraint PK_facet_shape_cut_c indicates that Parasolid must cut any
  facets containing interior holes before output. This can sometimes generate
  cases where the modified facets have concave interior angles.

  The constraint PK_facet_shape_convex_c indicates that Parasolid must cut
  any facets containing holes and further divide any concave facets into convex
  facets before output.

  The PK_facet_shape_cut_c and PK_facet_shape_convex_c constraints are only
  relevant when max_facet_sides > 3.

MATCH
  This field controls vertex matching between adjacent faces.

  The options are

  PK_facet_match_geom_c   : clip facet boundaries to a common edge
  PK_facet_match_topol_c  : match facet vertices across a common edge (default)
  PK_facet_match_trimmed_c: clip facet boundaries to model edge curve

  |   |    |   |       |   |   |    |   |   | | |     |      | |           |
  |...|....|...|.......|   |...|....|...|...|.|.|     |......|.|...........|
  |   |    |   |       |   |   |    |   |   | | |     |      B |           |
  |   |    |   |       |   |   |    |   |   | | |     |     / \|           |
  |   |    |   |       |   |   |    |   |   | | |     |    /   C-----------Y
  X---x----x---x---x-x-Y   X---x----x---x---x-x-Y     X---A---------D     /|
  |   |            | | |   |   |    |   |   | | |     |   |         |\   / |
  |   |            | | |   |   |    |   |   | | |     |   |         | \ /  |
  |   |            | | |   |   |    |   |   | | |     |   |         |  E   |
  |...|............|.|.|   |...|....|...|...|.|.|     |...|.........|..|...|
  |   |            | | |   |   |    |   |   | | |     |   |         |  |   |

  PK_facet_match_geom_c    PK_facet_match_topol_c     PK_facet_match_trimmed_c
  ---------------------    ----------------------     ------------------------

  The above diagram illustrates a (contrived) example of the facets created
  along an edge XY between two adjacent faces with the various matching
  options.  The dotted lines indicate the curve chord tolerance of the curve on
  edge XY.

  Actual examples of facets created using various matching options
  can be found in the match section of facetting in the functional description.

  The PK_facet_match_trimmed_c option clips exterior facets to within
  curve_chord_tol of the appropriate model edge but does no matching. If this
  option is selected, facets will, in general, overlap or leave gaps at the
  boundaries of adjacent faces.  In the above example a gap defined by ABCYEDA
  exists at the boundary of the two faces.

  The PK_facet_match_geom_c option modifies the geometry of such facet meshes
  by clipping (and possibly extending) exterior facets to meet at the common
  edge formed by the intersection of the underlying facet planes.

  There are certain special cases in which facet meshes may not match
  these are discussed in the functional description.

  If the application inputs a list of faces Parasolid recognises faces that
  belong to the same body and have identical transform entities, in this case
  facets will be clipped to common edges unless the option ignore_scope
  is set to PK_facet_ignore_scope_local_c (see ignore_scope option under
  IGNORING SMALL FEATURES below).

  The PK_facet_match_topol_c option further modifies the facet mesh so that
  facet vertices are matched across the common edge. The algorithm identifies
  cases where an exterior vertex on one facet mesh lies between a connected
  pair of exterior vertices on the other facet mesh and inserts a matching
  vertex.


DENSITY
  The facet density option allows the density of the facet mesh to be increased
  locally in regions where facet normals change from being front facing to
  back facing.  That is, where facet normals change from being within pi/2 to
  not being within pi/2 of the view direction specified in view_transf or the
  view directions given in view_directions if specified.

  This option is used when generating view specific facet meshes for use by
  rendering packages when creating high quality images (containing enhanced
  detail where the facet surfaces form silhouettes with the view direction).

  This field can take the following values :

  PK_facet_density_no_view_c  : facet density is independent of view (default)
  PK_facet_density_use_view_c : increase facet density at view silhouettes

  The PK_facet_density_no_view_c refers to no other arguments.

  The PK_facet_density_use_view_c argument requires the following values

      - the view_transf argument and view_directions argument.  If
        view_directions have been specified these directions will override
        the single direction specified in the view_transf.

      - the local_density_tol tolerance value,

  and optionally,

      - the local_density_ang tolerance value

  The view_transf may contain perspective but only the direction component
  will be used.

CULL
  This is a performance enhancement option for use when creating view
  specific images from facet data (possibly in conjunction with the
  the PK_facet_density_use_view_c option).

  It can also be used to reduce the amount of facet data which are output.

  This field can take the following values :

  PK_facet_cull_none_c : do not cull any facets; output them all      (default)
  PK_facet_cull_back_c : cull back facing facets

  The PK_facet_cull_none_c outputs all faces (and refers to no other arguments)

  The PK_facet_cull_back_c argument requires the view_transf to be set to a
  viewing transformation which may contain perspective.

  It is not possible to request (the default) topology matching with this
  option, PK_facet_match_geom_c or PK_facet_match_trimmed_c must be specified.

  This option reduces the size of the generated facet mesh (and consequently
  the amount of topological and geometric data which are output) by not
  facetting back facing faces.  A back facing face is one whose normal at
  every point is backwards facing.  If a face cannot quickly be identified as
  back facing it will be facetted.

  This option has no effect on sheet bodies.


LOOPS
  The loops option allows specific holes in a sheet body to be capped.
  These are specified as an array of interior loops (being ones owned
  by sheet bodies or faces which are included in the topol array').

  These interior loops are ignored during facetting; the effect is
  to extend the surface geometry of the surrounding sheet face across
  the loop.

  The PK_TOPOL_facet_mesh_m macro initialises the loops array to be empty

        n_loops = 0


FACET SIZE AND NUMBER OF SIDES
  The max_facet_sides option controls the maximum number sides that any facet
  can have and must take a value of 3 or more.

  The options is_min_facet_width and is_max_facet_width control the minimum
  and maximum lengths of any of the facets sides.  To set an explicit value
  for such constraints, the associated field
                        min_facet_width
                     or max_facet_width
  is set to a positive value (specified in model units) and the associated flag
  is set to PK_LOGICAL_true.

  In cases where refinement results in a facet being created that has a width
  smaller than min_facet_width Parasolid will disregard the supplied curve,
  surface and planarity tolerances so that the new facet will not be refined
  any further.  Therefore facets may exist with dimensions smaller than
  min_facet_width.


CURVE TOLERANCE

  The following arguments control curve tolerance values, measuring how closely
  a curved edge entity is approximated by a number of straight line chords.

  Three curve tolerance controls are provided :

        curve_chord_tol   : the maximum chordal distance between a
                            facet edge and its original edge entity

        curve_chord_max   : the maximum length of any facet edge which
                            represents part of an original edge entity

        curve_chord_ang   : the maximum angle which is permitted between
                            a facet chord and its original edge entity,
                            measured as the sum of the two angles formed
                            between the chord and the curve tangents at
                            each chord end.

  To set one or more of these constraints, the value is set to a positive
  value and the associated flag set to PK_LOGICAL_true.

SURFACE TOLERANCE
  The following arguments control surface tolerance values, measuring
  how closely any curved surface attached to a face is approximated
  by a facet mesh.

  Two surface tolerance controls are provided :

        surface_plane_tol : the maximum distance between the mid-plane
                            of a facet and its original face entity

        surface_plane_ang : the maximum angle (in radians) which is permitted
                            between the surface normals at any two positions
                            on the surface which lie within the facet boundary
                            (this is usually met but it is not guaranteed).


PLANARITY TOLERANCE
  The "facet to mid-plane" tolerances control how closely vertices lie on
  a common plane. The `mid-plane' of a facet used in this calculation is
  defined to pass through the centre of gravity of the vertex points in the
  direction of the sum of the vertex normals.

  Two planarity tolerance controls are provided :

        facet_plane_tol :   the maximum distance between the mid-plane
                            of a facet and its facet vertices

        facet_plane_ang :   the maximum ratio permitted between :

                            1) the maximum distance from the mid-plane
                               of a facet to any of its facet vertices

                            2) the maximum width of a facet.


LOCAL FACET DENSITY TOLERANCE
  The "silhouette_density" tolerance values are used in conjunction
  with the PK_facet_density_use_view_c density option. These define
  local surface tolerance values to be used when generating facets
  in the region of view dependent facet silhouettes.

  Two local facet density tolerance controls are provided:

        local_density_tol :  the maximum distance between the mid_plane of a
                             facet and its original face entity.

        local_density_ang :  the maximum angle (in radians) which is permitted
                             between the surface normals at any two positions
                             on the surface which lie within the facet boundary
                             (this is ususally met but it is not guaranteed).

  If the PK_facet_density_use_view_c option is requested the
  is_local_density_tol flag and its associated value must be set (to a
  positive value) otherwise the option in ignored.

  It is also possible (although not compulsory) to set the
  is_local_density_ang flag, once again the associated value must be
  positive.


OUTPUT AT DEGENERACIES
  The behaviour of the facetting operation at degenerate vertices can be
  modified via the degen option.

  The permitted values for this option:

  PK_facet_degen_multiple_vxs_c: (default)
  The function will create multiple vertices at degeneracies.  Each facet that
  is adjacent to a degeneracy will have a unique vertex at the degeneracy.
  This ensures the correct parameters, normals and derivatives will be
  returned for the facet at the degeneracy. All of the vertices at the
  degeneracy will reference the same point.

  PK_facet_degen_single_vx_c:
  The function will create single vertices at degeneracies, this vertex can
  only have one parameter, normal and derivative associated with it, thus all
  facets adjacent to a degeneracy will have the same value for the parameter,
  normal and derivative for the vertex at the degeneracy. In this case the
  facet topology is correct.  This option only has an effect on the output
  returned though the tables in PK_TOPOL_facet, it does not have any effect
  if used in conjunction with PK_TOPOL_render_facet.

  PK_facet_degen_average_parms_c:
  The function will create multiple vertices at degeneracies in the same way
  as the 'PK_face_degen_multiple_vxs_c' option, in this case when a facet
  vertex occurs at a degeneracy, the value of the degenerate parameter at the
  degenerate vertex will be the average of the values of that parameter at the
  two facet vertices on either side of the degenerate vertex.  The normals and
  derivatives at the degenerate vertex will be evaluated using this average
  value for the degenerate parameter.

  More details and a diagram can be found in vertices at degeneracies


INCREASING SILHOUETTE DENSITY IN MULTIPLE DIRECTIONS
  The view_directions option allows the facet density to be increased in
  multiple view directions.  These view directions are specified as an array of
  unit vectors.

  These view directions override the direction given in view_transf as far as
  increasing the facet density is concerned, that is, the facet density will
  be increased in all the directions specified in view_directions.

  The PK_TOPOL_facet_mesh_m macro initialises the view_directions array to be
  empty
        n_view_directions = 0

  in this case facet density will be increased in the direction specified in
  the option view_transf.


FACETTING TOPOLOGICAL ENTITIES WITH LOCAL TOLERANCES

  It is possible to attach local tolerances to individual or groups of
  topological entities (either faces or bodies), these local tolerances will
  then override the facetting tolerances for the particular face/body.

  In order to facet certain entities with local tolerances it is necessary
  to fill in the following fields:

  local_tols
  This field is an array of PK_facet_local_tolerances_t.  This array contains
  all local tolerance sets to be attached to topological entities.

  topols_with_local_tols
  This field takes an array of unique topological entities (faces or bodies)
  which are to be facetted using local tolerances.  If this is empty all
  entities will be facetted to the tolerances previously specified in the
  options structure.  If this is not empty the parallel array
  local_tols_for_topols must be filled in.

  local_tols_for_topols
  This field must be of length n_topols_with_local_tols, and takes integer
  values corresponding to indexes into the local_tols array.  For
  each topological entity in topols_with_local_tols, the corresponding entry
  in local_tols_for_topols is the index into local_tols corresponding to
  the PK_facet_local_tolerances with which the entity is to be facetted.

  When finding the tolerances to use when facetting a paticular face, the
  tolerances are initially set to the default tolerances.  If any tolerances
  were specified in the options structure these tolerances overwrite the
  default tolerances.  If the face's owning body has local facet tolerances
  specified these tolerances (provided they are not set to 0.0) override any
  existing tolerances for this face.  If the face itself has local facet
  tolerances specified these tolerances will override any existing tolerances
  for this face (provided they are not 0.0).

  The curve tolerance along an edge will be the minimum local curve tolerance
  of the edge's faces.

  The PK_TOPOL_facet_mesh_o_m initialises the local_tols array to be empty
        n_local_tols = 0,

  topols_with_local_tols is also initialised to be empty
       n_topols_with_local_tols = 0,

  in this case all entities will be facetted using the facetting tolerances
  given above.


IGNORING SMALL FEATURES
  The ignore option allows small features to be ignored when facetting.
  The value specified in ignore_value defines which features are classed as
  small.  The overall box is the box containing all entities to be facetted.

  The permitted values for this option:

  PK_facet_ignore_no_c: (default)
  All features will be facetted regardless of size.

  PK_facet_ignore_absolute_c:
  Any feature with a box size smaller than the value specified in
  ignore_value may be ignored.

  PK_facet_ignore_ratio_c:
  Here ignore_value corresponds to the ratio of box size of the feature to
  the size of the overall box i.e. if this value is set to 0.01 then features
  smaller than 1 per-cent of the overall box may be ignored. If facetting
  bodies the overall box will be the union of all the topols boxes (with
  topol_transfs applied), if faces are being facetted the overall box will
  depend on local_scope as described below.

  PK_facet_ignore_body_ratio_c:
  ignore_value corresponds to the ratio of the box size of the feature to
  the size of the box of the body containing the feature.

  Note that if the option loop has been specified, facetting will ignore the
  given loops regardless of the value of the ignore option.

  The option ignore_scope only has an effect when facetting lists of faces,
  the permitted values for this option:

  PK_facet_ignore_scope_global_c: (default)
  Ensures that the only loops ignored on a face when facetting a list of faces
  are the loops that would have been ignored had the face's owning body been
  facetted, thus small holes in the face will not be ignored if the loop
  defining the hole is adjacent to faces that are not classed as small.  In
  this case the overall box will be the union of all of the topols owning
  bodies boxes (with topol_transfs applied).

  PK_facet_ignore_scope_local_c:
  When looking for ignorable features the faces in the list of faces will be
  facetted as separate entities, hence there will be no matching between
  adjacent faces.  If the face contains holes defined by loops which can be
  classed as small these will be ignored.  In this case the overall box will be
  the union of all the topols boxes (with topol_transfs applied).



WIRE EDGES
  The behaviour of the facetting operation on faces which contain wire edges
  can be modified via the wire_edges option.

  The permitted values for this option:

  PK_facet_wire_edges_no_c: (default)
  Facetting will ignore wire edges in faces, they will be facetted over.

  PK_facet_wire_edges_yes_c:
  Facetting will take wire edges in faces into account and will facet the face
  in such a way that no facet is intersected by a wire edge.