PK_BSURF_sf_t   


struct PK_BSURF_sf_s
    {
    int u_degree;                           --- The degree in u = order-1.
    int v_degree;                           --- The degree in v = order-1.
    int n_u_vertices;                       --- The number of vertices in u.
    int n_v_vertices;                       --- The number of vertices in v.
    int vertex_dim;                         --- The dimension of each vertex.
    PK_LOGICAL_t is_rational;               --- True if the surface is rational
    double *vertex;                         --- The vertices.
    PK_BSURF_form_t form;                   --- The surface shape.
    int n_u_knots;                          --- The number of knot values in u.
    int n_v_knots;                          --- The number of knot values in v.
    int *u_knot_mult;                       --- The multiplicities in u.
    int *v_knot_mult;                       --- The multiplicities in v.
    double *u_knot;                         --- The distinct knot values in u.
    double *v_knot;                         --- The distinct knot values in v.
    PK_knot_type_t u_knot_type;             --- Enum describing the u knot set.
    PK_knot_type_t v_knot_type;             --- Enum describing the v knot set.
    PK_LOGICAL_t is_u_periodic;             --- Periodic in u.
    PK_LOGICAL_t is_v_periodic;             --- Periodic in v.
    PK_LOGICAL_t is_u_closed;               --- Closed in u.
    PK_LOGICAL_t is_v_closed;               --- Closed in v.
    PK_self_intersect_t self_intersecting;  --- Yes no or maybe.
    PK_convexity_t convexity;               --- Yes no or maybe.
    };
typedef struct PK_BSURF_sf_s PK_BSURF_sf_t;


This data structure is the standard form for a b-surface.  See the
documentation below for the relationship between this data structure and STEP.


Specific Errors:
PK_ERROR_bad_value              unreadable value
PK_ERROR_bad_knots              illegal knot multiplicity
                                or knot set not monotonic increasing
PK_ERROR_wrong_number_knots     knots inconsistent with vertices
PK_ERROR_bad_dimension          dimension < 1 polynomial or < 2 rational
PK_ERROR_weight_le_0            one of the weights is zero or negative



Converting between PK_BSURF_sf_t and STEP:

    This form is easily convertible to the STEP standard, but there are a
    number of important differences, designed to make its use simpler and more
    efficient.


vertex_dim:

    This field gives the number of doubles per vertex in the array vertex.
    Allowable values are 3 and 4. A value of 3 implies a 3-d polynomial
    surface. A value of 4 implies a 3-d rational surface. The STEP
    "cartesian_point" entity allows 1, 2 or 3.


is_rational:

    This field is set to true if the surface is rational. In this case the
    vertex_dim field must be 4, and the weights must be included in the
    vertex array. The STEP standard uses a distinct entity subtype
    "rational_b_spline_surface".


vertex:

    If the surface is polynomial, dimension 3, then the values in this field
    represent the vertices explicitly, in the order [x1, y1, z1, x2, y2, ...]
    respectively. If it is rational, dimension 4, then the cartesian points
    are multiplied by the weights, so that the values in this field represent
    x1w1, y1w1, z1w1, w1, x2w2, y2w2, ...]. The vertices are so arranged that
    they vary most quickly with v and then with u. The STEP standard uses a
    separate array of weights, and does not multiply the cartesian points by
    the weights.


form:

    See the documentation of PK_BSURF_form_t.
    This field corresponds to the field of the same name in the STEP
    "b_spline_surface" entity, except for the PK_BSURF_form_unset_c value
    which does not exist in the STEP standard.


u_knot_mult v_knot_mult u_knot and v_knot:

    The values in u_knot_mult and v_knot_mult give the number of times
    each knot is to be repeated. The minimum multiplicity allowed for any knot
    is 1. The maximum multiplicity allowed other than for the first and last
    knot is the degree in that parameter. The maximum allowed for the first or
    last knot is the degree+1.

    The values in u_knot and  v_knot must be  distinct  and form a monotone
    increasing set.

    See the documentation below for an explanation of the required total
    number of knots.

    These arrays correspond exactly to the fields "u_multiplicities"
    "v_multiplicities" "u_knots" and "v_knots" in the STEP entity sub-type
    "b_spline_surface_with_knots".


u_knot_type and v_knot_type:

    See the documentation for PK_knot_type_t. The STEP standard does not
    contain a field corresponding to these.  The information described is
    conveyed by the use of entity subtypes, such as "bezier_surface".  The
    values PK_knot_bezier_ends_c and PK_knot_non_uniform_c have no
    corresponding subtype. A surface of one of these types would be translated
    to STEP as a "bspline_surface_with_knots". For a surface to be translated
    as, for instance "uniform_surface", both knot types would have to be
    uniform. Otherwise it would default to the more general
    "bspline_surface_with_knots".


is_u_periodic and is_v_periodic:

    If either of these fields is set to true, the parametrisation of the
    surface "wraps around".  It implies that the surface is closed in that
    direction, with G1 continuity at the seam.  This field does not exist in
    the STEP standard.

    See the documentation below for additional requirements for the knot sets
    of a periodic b-surface.


is_u_closed and is_v_closed:

    One or both of these fields being set to true does not necessarily imply
    that the parametrisation is periodic. They correspond to the fields of the
    same name in the STEP entity "b_spline_surface".


self_intersecting:

    See the documentation of PK_self_intersect_t.
    This corresponds to the field "self_intersect" in the STEP entity
    "b_spline_surface", except that the STEP standard does not provide for an
    unset value.

convexity:

    See the documentation of PK_convexity_t.
    This field has no correspondence in the STEP "b_spline_surface" entity.
    Surfaces being converted from STEP should be given a value of
    PK_convexity_unset_c.


The number of knots:

The knot set referred to here is the "expanded  knot set" obtained by repeating
each value in the array u_knot or v_knot the  number of times given  by the
corresponding element in u_knot_mult or v_knot_mult.

A NURBS surface of degree n in one of its parameters defined over k values
k-1 intervals) in that parameter requires a further n values at either end of
that knot set in order for the necessary k+n-1 b-spline basis functions to be
fully defined. These additional values are commonly known as the "imaginary
knots". Thus the total number of knots p is related to the total number of
basis functions and hence the number m of control vertices in that direction
the number of rows or collumns) by the expression p = m+n+1.


Periodic Surfaces:

A periodic surface must be so constructed as to preserve G1 continuity
(of tangent direction) at the seam.

In addition, it is recommended that a periodic surface be constructed
with C(n-1) continuity at the seam (where n is the degree). This would
give C2 continuity at the seam for a cubic. This is most easily achieved
by making the "expanded knot set" "wrap around" in the sense that the
intervals between the first n+1 knots (n "imaginary" knots and one "real"
knot) should be the same as the corresponding intervals between the last
n+1 "real" knots, and the intervals between the last n+1 knots (one "real"
knot and n "imaginary" knots) should be the same as those between the first
n+1 "real" knots.

The "period" of such a surface is the parameter interval separating the first
and last "real" knots in the periodic parameter direction.

if indices begin at 0:
    period = u_or_v     - u_or_v
                   k+n-1        n

for i = 0 to n:
    u_or_v       - period = u_or_v
          k+n+i-1                 n+i

    u_or_v + period = u_or_v
          i                 k+i-1