Surfaces

Two type of surfaces are available:

  • B-splines surfaces
  • NURBS surfaces

Both are defined by initializing corresponding structures.


Defining Structures

NURBS and B-spline surfaces are defined by initializing a BsplineSurface or a NURBSsurface structure, respectively.

using StaticArrays

# --- parameters
kVec = Float64[0, 0, 0, 1, 2, 3, 4, 5, 5, 5] # knot vector
kVec ./= maximum(kVec)                       # normalize it

p = 2 # degree of the basis

# --- control points
controlPoints = [[SVector(0.0,0.0,3.0), SVector(0.0,1.0,3.0), SVector(0.0,2.0,2.0), SVector(0.0,3.0,2.0), SVector(0.0,4.0,2.0), SVector(0.0,5.0,2.0), SVector(0.0,6.0,2.0)],
                 [SVector(1.0,0.0,3.0), SVector(1.0,1.0,3.0), SVector(1.0,2.0,2.0), SVector(1.0,3.0,2.0), SVector(1.0,4.0,2.0), SVector(1.0,5.0,2.0), SVector(1.0,6.0,2.0)],
                 [SVector(2.0,0.0,2.0), SVector(2.0,1.0,2.0), SVector(2.0,2.0,1.0), SVector(2.0,3.0,1.0), SVector(2.0,4.0,1.0), SVector(2.0,5.0,1.0), SVector(2.0,6.0,1.0)],
                 [SVector(3.0,0.0,2.0), SVector(3.0,1.0,2.0), SVector(3.0,2.0,1.0), SVector(3.0,3.0,1.0), SVector(3.0,4.0,1.0), SVector(3.0,5.0,0.0), SVector(3.0,7.0,0.0)],
                 [SVector(4.0,0.0,1.0), SVector(4.0,1.0,1.0), SVector(4.0,2.0,0.0), SVector(4.0,3.0,0.0), SVector(4.0,4.0,1.0), SVector(4.0,5.0,0.0), SVector(4.0,6.0,0.0)],
                 [SVector(5.0,0.0,1.0), SVector(5.0,1.0,1.0), SVector(5.0,2.0,0.0), SVector(5.0,3.0,0.0), SVector(5.0,4.0,0.0), SVector(5.0,5.0,0.0), SVector(5.0,6.0,0.0)],
                 [SVector(6.0,0.0,1.0), SVector(6.0,1.0,1.0), SVector(6.0,2.0,0.0), SVector(6.0,3.0,0.0), SVector(6.0,4.0,0.0), SVector(6.0,5.0,0.0), SVector(6.0,6.0,0.0)]]

controlPoints = [controlPoints[i][j] for i in 1:7, j in 1:7]

# --- weights for the NURBS basis
w = ones(size(controlPoints))
w[5,5] = 2.0
w[7,2] = 0.8

# --- initialize structures (using the same basis in both parametric directions)
BSurface = BsplineSurface(Bspline(p, kVec), Bspline(p, kVec), controlPoints)
NSurface = NURBSsurface(Bspline(p, kVec), Bspline(p, kVec), controlPoints, w)

Evaluate Points on a Surface

To evaluate the surfaces at parametric points hand over the latter.

uEvalpoints = collect(0:0.01:1.0)
vEvalpoints = collect(0:0.01:1.0)

SBspline = BSurface(uEvalpoints, vEvalpoints)
SNurbs   = NSurface(uEvalpoints, vEvalpoints)

To plot the surfaces the plotSurface or the plotPatches functions are provided, where the latter evaluates the surface points itself.

Note

The PlotlyJS.jl package has to be loaded in order to make the functions available. (It is a weak dependency.)

using PlotlyJS

plotSurface(SNurbs, controlPoints=controlPoints)

# alternatively
#plotPatches([NSurface], plotControlPoints=true)

Evaluate Derivatives of a Surface

To evaluate derivatives of surfaces at parametric points hand over the latter and the maximum derivative to be evaluated.

uEvalpoints = collect(0:0.01:1.0)
vEvalpoints = collect(0:0.01:1.0)

S = NSurface(uEvalpoints, vEvalpoints, 2) # 0-th, 1st, and 2nd derivatives

In case points (e.g., single points) shall be evaluated many times on demand, memory can be preallocated and reused in subsequent calls:

pM = NURBS.preAllocNURBSsurface(p, p, uEvalpoints, vEvalpoints, 2)

S = NSurface(uEvalpoints, vEvalpoints, 2, pM)

The plotSurface function has an optional argument tangents to plot vectors at the points of the curve.

using PlotlyJS

plotSurface(S[1, 1], tangents=S[2,1], controlPoints=NSurface.controlPoints, enforceRatio=false)