#### Previous topic

49. neu_exp — Gambit neutral file exporter.

#### Next topic

51. objects — Selection of objects from the global dictionary.

# 50. nurbs — Using NURBS in pyFormex.¶

The nurbs module defines functions and classes to manipulate NURBS curves and surface in pyFormex.

Classes defined in module nurbs

class nurbs.Coords4

A collection of points represented by their homogeneous coordinates.

While most of the pyFormex implementation is based on the 3D Cartesian coordinates class Coords, some applications may benefit from using homogeneous coordinates. The class Coords4 provides some basic functions and conversion to and from cartesian coordinates. Through the conversion, all other pyFormex functions, such as transformations, are available.

Coords4 is implemented as a float type numpy.ndarray whose last axis has a length equal to 4. Each set of 4 values (x,y,z,w) along the last axis represents a single point in 3D space. The cartesian coordinates of the point are obtained by dividing the first three values by the fourth: (x/w, y/w, z/w). A zero w-value represents a point at infinity. Converting such points to Coords will result in Inf or NaN values in the resulting object.

The float datatype is only checked at creation time. It is the responsibility of the user to keep this consistent throughout the lifetime of the object.

Just like Coords, the class Coords4 is derived from numpy.ndarray.

Parameters:

data: array_like
If specified, data should evaluate to an array of floats, with the length of its last axis not larger than 4. When equal to four, each tuple along the last axis represents a ingle point in homogeneous coordinates. If smaller than four, the last axis will be expanded to four by adding values zero in the second and third position and values 1 in the last position. If no data are given, a single point (0.,0.,0.) will be created.
w: array_like
If specified, the w values are used to denormalize the homogeneous data such that the last component becomes w.
dtyp: data-type
The datatype to be used. It not specified, the datatype of data is used, or the default Float (which is equivalent to numpy.float32).
copy: boolean
If True, the data are copied. By default, the original data are used if possible, e.g. if a correctly shaped and typed numpy.ndarray is specified.
normalize()

Normalize the homogeneous coordinates.

Two sets of homogeneous coordinates that differ only by a multiplicative constant refer to the same points in cartesian space. Normalization of the coordinates is a way to make the representation of a single point unique. Normalization is done so that the last component (w) is equal to 1.

The normalization of the coordinates is done in place.

Warning

Normalizing points at infinity will result in Inf or NaN values.

deNormalize(w)

Denormalizes the homogeneous coordinates.

This multiplies the homogeneous coordinates with the values w. w normally is a constant or an array with shape self.shape[:-1] + (1,). It then multiplies all 4 coordinates of a point with the same value, thus resulting in a denormalization while keeping the position of the point unchanged.

The denormalization of the coordinates is done in place. If the Coords4 object was normalized, it will have precisely w as its 4-th coordinate value after the call.

toCoords()

Convert homogeneous coordinates to cartesian coordinates.

Returns:

A Coords object with the cartesian coordinates of the points. Points at infinity (w=0) will result in Inf or NaN value. If there are no points at infinity, the resulting Coords point set is equivalent to the Coords4 one.

npoints()

Return the total number of points.

ncoords()

Return the total number of points.

x()

Return the x-plane

y()

Return the y-plane

z()

Return the z-plane

w()

Return the w-plane

bbox()

Return the bounding box of a set of points.

Returns the bounding box of the cartesian coordinates of the object.

actor(**kargs)

Graphical representation

class nurbs.NurbsCurve(control, degree=None, wts=None, knots=None, closed=False, blended=True)

A NURBS curve

The Nurbs curve is defined by nctrl control points, a degree (>= 1) and a knot vector with knots = nctrl+degree+1 parameter values.

The knots vector should hold nknots values in ascending order. The values are only defined upon a multiplicative constant and will be normalized to set the last value to 1. Sensible default values are constructed automatically by calling knotVector().

If no knots are given and no degree is specified, the degree is set to the number of control points - 1 if the curve is blended. If not blended, the degree is not set larger than 3.

bbox()

Return the bounding box of the NURBS curve.

pointsAt(u)

Return the points on the Nurbs curve at given parametric values.

Parameters:

• u: (nu,) shaped float array, parametric values at which a point is to be placed.

Returns (nu,3) shaped Coords with nu points at the specified parametric values.

derivs(at, d=1)

Returns the points and derivatives up to d at parameter values at

knotPoints()

Returns the points at the knot values.

The multiplicity of the knots is retained in the points set.

insertKnots(u)

Insert a set of knots in the curve.

u is a vector with knot parameter values to be inserted into the curve. The control points are adapted to keep the curve unchanged.

Returns:

A Nurbs curve equivalent with the original but with the specified knot values inserted in the knot vector, and the control points adapted.

decompose()

Decomposes a curve in subsequent Bezier curves.

Returns an equivalent unblended Nurbs.

removeKnots(u, tol)

Remove a knots in the curve.

u is a vector with knot parameter values to be inserted into the curve. The control points are adapted to keep the curve unchanged.

Returns:

A Nurbs curve equivalent with the original but with the specified knot values inserted in the knot vector, and the control points adapted.

approx(ndiv=None, ntot=None)

Return a PolyLine approximation of the Nurbs curve

If no ntot is given, the curve is approximated by a PolyLine through equidistant ndiv+1 point in parameter space. These points may be far from equidistant in Cartesian space.

If ntot is given, a second approximation is computed with ntot straight segments of nearly equal length. The lengths are computed based on the first approximation with ndiv segments.

actor(**kargs)

Graphical representation

class nurbs.NurbsSurface(control, degree=(None, None), wts=None, knots=(None, None), closed=(False, False), blended=(True, True))

A NURBS surface

The Nurbs surface is defined as a tensor product of NURBS curves in two parametrical directions u and v. The control points form a grid of (nctrlu,nctrlv) points. The other data are like those for a NURBS curve, but need to be specified as a tuple for the (u,v) directions.

The knot values are only defined upon a multiplicative constant, equal to the largest value. Sensible default values are constructed automatically by a call to the knotVector() function.

If no knots are given and no degree is specified, the degree is set to the number of control points - 1 if the curve is blended. If not blended, the degree is not set larger than 3.

Warning

This is a class under development!

bbox()

Return the bounding box of the NURBS surface.

pointsAt(u)

Return the points on the Nurbs surface at given parametric values.

Parameters:

• u: (nu,2) shaped float array: nu parametric values (u,v) at which a point is to be placed.

Returns (nu,3) shaped Coords with nu points at the specified parametric values.

derivs(u, m)

Return points and derivatives at given parametric values.

Parameters:

• u: (nu,2) shaped float array: nu parametric values (u,v) at which the points and derivatives are evaluated.
• m: tuple of two int values (mu,mv). The points and derivatives up to order mu in u direction and mv in v direction are returned.

Returns:

(nu+1,nv+1,nu,3) shaped Coords with nu points at the specified parametric values. The slice (0,0,:,:) contains the points.

actor(**kargs)

Graphical representation

Functions defined in module nurbs

nurbs.globalInterpolationCurve(Q, degree=3, strategy=0.5)

Create a global interpolation NurbsCurve.

Given an ordered set of points Q, the globalInterpolationCurve is a NURBS curve of the given degree, passing through all the points.

Returns:

A NurbsCurve through the given point set. The number of control points is the same as the number of input points.

Warning

Currently there is the limitation that two consecutive points should not coincide. If they do, a warning is shown and the double points will be removed.

The procedure works by computing the control points that will produce a NurbsCurve with the given points occurring at predefined parameter values. The strategy to set this values uses a parameter as exponent. Different values produce (slighly) different curves. Typical values are:

0.0: equally spaced (not recommended) 0.5: centripetal (default, recommended) 1.0: chord length (often used)

nurbs.uniformParamValues(n, umin=0.0, umax=1.0)

Create a set of uniformly distributed parameter values in a range.

Parameters:

• n: int: number of intervals in which the range should be divided. The number of values returned is n+1.
• umin, umax: float: start and end value of the interval. Default interval is [0.0..1.0].

Returns:

A float array with n+1 equidistant values in the range umin..umax. For n > 0, both of the endpoints are included. For n=0, a single value at the center of the interval will be returned. For n<0, an empty array is returned.

Example:

```>>> uniformParamValues(4).tolist()
[0.0, 0.25, 0.5, 0.75, 1.0]
>>> uniformParamValues(0).tolist()
[0.5]
>>> uniformParamValues(-1).tolist()
[]
>>> uniformParamValues(2,1.5,2.5).tolist()
[1.5, 2.0, 2.5]
```
nurbs.knotVector(nctrl, degree, blended=True, closed=False)

Compute sensible knot vector for a Nurbs curve.

A knot vector is a sequence of non-decreasing parametric values. These values define the knots, i.e. the points where the analytical expression of the Nurbs curve may change. The knot values are only meaningful upon a multiplicative constant, and they are usually normalized to the range [0.0..1.0].

A Nurbs curve with nctrl points and of given degree needs a knot vector with nknots = nctrl+degree+1 values. A degree curve needs at least nctrl = degree+1 control points, and thus at least nknots = 2*(degree+1) knot values.

To make an open curve start and end in its end points, it needs knots with multiplicity degree+1 at its ends. Thus, for an open blended curve, the default policy is to set the knot values at the ends to 0.0, resp. 1.0, both with multiplicity degree+1, and to spread the remaining nctrl - degree - 1 values equally over the interval.

For a closed (blended) curve, the knots are equally spread over the interval, all having a multiplicity 1 for maximum continuity of the curve.

For an open unblended curve, all internal knots get multiplicity degree. This results in a curve that is only one time continuously derivable at the knots, thus the curve is smooth, but the curvature may be discontinuous. There is an extra requirement in this case: nctrl sohuld be a multiple of degree plus 1.

Example:

```>>> print knotVector(7,3)
[ 0.    0.    0.    0.    0.25  0.5   0.75  1.    1.    1.    1.  ]
>>> print knotVector(7,3,closed=True)
[ 0.   0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9  1. ]
>>> print knotVector(7,3,blended=False)
[ 0.  0.  0.  0.  1.  1.  1.  2.  2.  2.  2.]
```
nurbs.toCoords4(x)

Convert cartesian coordinates to homogeneous

x: Coords
Array with cartesian coordinates.

Returns a Coords4 object corresponding to the input cartesian coordinates.

nurbs.pointsOnBezierCurve(P, u)

Compute points on a Bezier curve

Parameters:

P is an array with n+1 points defining a Bezier curve of degree n. u is a vector with nu parameter values between 0 and 1.

Returns:

An array with the nu points of the Bezier curve corresponding with the specified parametric values. ERROR: currently u is a single paramtric value!

nurbs.deCasteljou(P, u)

Compute points on a Bezier curve using deCasteljou algorithm

Parameters:

P is an array with n+1 points defining a Bezier curve of degree n. u is a single parameter value between 0 and 1.

Returns:

A list with point sets obtained in the subsequent deCasteljou approximations. The first one is the set of control points, the last one is the point on the Bezier curve.

This function works with Coords as well as Coords4 points.

nurbs.curveToNurbs(B)

Convert a BezierSpline to NurbsCurve

nurbs.polylineToNurbs(B)

Convert a PolyLine to NurbsCurve

nurbs.frenet(d1, d2, d3=None)

Returns the 3 Frenet vectors and the curvature.

Parameters:

• d1: first derivative at npts points of a nurbs curve
• d2: second derivative at npts points of a nurbs curve
• d3: (optional) third derivative at npts points of a nurbs curve

The derivatives of the nurbs curve are normally obtained from NurbsCurve.deriv().

Returns:

• T: normalized tangent vector to the curve at npts points
• N: normalized normal vector to the curve at npts points
• B: normalized binormal vector to the curve at npts points
• k: curvature of the curve at npts points
• t: (only if d3 was specified) torsion of the curve at npts points