.. role:: code :class: code NURBS Surface Construction ============================= .. _NURBS_Surface_Construction_: .. kernel version: 118056 The function .. code-block:: cpp MbResultType SplineSurface( const MbCartPoint3D & pUMinVMin, const MbCartPoint3D & pUMaxVMin, const MbCartPoint3D & pUMaxVMax, const MbCartPoint3D & pUMinVMax, size_t uCount, size_t vCount, size_t uDegree, size_t vDegree, MbSurface *& result ); constructs a NURBS surface by corner control points. The input parameters of the function are: - **pUMinVMin** is a left lower corner point of the surface; - **pUMaxVMin** is a right lower corner point of the surface; - **pUMaxVMax** is a right upper corner point of the surface; - **pUMinVMax** is a left upper corner point of the surface; - **uCount** is a number of control points along the first parameter (horizontally); - **vCount** is a number of control points along the second parameter (vertically); - **uDegree** is an order of B-splines along the first parameter; - **vDegree** is an order of B-splines along the second parameter. The output parameter of the function is the constructed spline surface **result**. If successful, the function returns :code:`rt_Success`; otherwise, it returns an error code from the :ref:`MbResultType ` enumeration. The function is declared in the *action_surface.h* file. This function constructs a NURBS surface whose control points are located at the nodes of a quadrilateral grid with **uCount** columns and **vCount** rows. The order of the surface *B*-splines along the first parameter is equal to **uDegree**, and the order of the surface *B*-splines along the second parameter is equal to **vDegree**. The control points of the surface are calculated under the requirement of uniform distribution and coincidence of the corner points with the points **pUMinVMin**, **pUMaxVMin**, **pUMaxVMax**, **pUMinVMax**, see Fig. 1: .. figure:: ../../pictures/M.5.2.1.png :width: 15cm :align: center Fig. 1 The weights of all control points are equal to one. The constructed surface is intended for further modification. For the function parameters the following inequalities must hold: **uCount** ≥ **uDegree** and **vCount** ≥ **vDegree**. The NURBS surface is described in subsection :ref:`NURBS Surface MbSplineSurface `. The function .. code-block:: cpp MbResultType SplineSurface( const SArray & pointList, const SArray & weightList, size_t uCount, size_t vCount, size_t uDegree, const SArray & uKnotList, bool uClosed, size_t vDegree, const SArray & vKnotList, bool vClosed, MbSurface *& result ); constructs a NURBS surface by control points and their weights. The input parameters of the function are: - **pointList** is a set of control points conventionally arranged as **vCount** rows with **uCount** points in each row; - **weightList** is a set of weights of control points consistent with the set of control points; - **uCount** is a number of control points along the first parameter (in each row); - **vCount** is a number of control points along the second parameter (the number of rows); - **uDegree** is an order of B-splines along the first parameter; - **uKnotList** is a knot vector of the first parameter; - **uClosed** is a cyclic closedness of the surface along the first parameter; - **vDegree** is an order of B-splines along the second parameter; - **vKnotList** is a knot vector of the second parameter; - **vClosed** is a cyclic closedness of the surface along the second parameter. The output parameter of the function is the constructed surface **result**. If successful, the function returns :code:`rt_Success`; otherwise, it returns an error code from the :ref:`MbResultType ` enumeration. The function is declared in the *action_surface.h* file. This function constructs a NURBS surface with control points **pointList**. The control points of the **pointList** set are divided into conventional rows and columns. Each row contains **uCount** control points from the **pointList** set, and the number of rows is equal to **vCount**. Thus, the **pointList** set must contain **uCount**\ :sup:`.`\ **vCount** control points. The order of the surface *B*-splines along the first parameter is equal to **uDegree**, and the order of the surface *B*-splines along the second parameter is equal to **vDegree**. For the function parameters the following inequalities must hold: **uCount** ≥ **uDegree** and **vCount** ≥ **vDegree**. The NURBS surface is described in subsection :ref:`NURBS Surface MbSplineSurface `. The sets **weightList**, **uKnotList**, **vKnotList** may be empty. If the **weightList** set is empty, the weights of the control points are equal to one. If the **uKnotList** or **vKnotList** sets are empty, the knot vectors are generated automatically. If the **weightList** set is not empty, it must be consistent with the set of control points **pointList**. If the **uKnotList** and **vKnotList** sets are not empty, they must contain a certain number of elements: for **uClosed** = *false*, the **uKnotList** knot vector must contain **uCount** + **uDegree** elements; for **uClosed** = *true*, the **uKnotList** knot vector must contain **uCount** + 2 · **uDegree** - 1 elements; for **vClosed** = *false*, the **vKnotList** knot vector must contain **vCount** + **vDegree** elements; for **vClosed** = *true*, the **vKnotList** knot vector must contain **vCount** + 2 · **vDegree** - 1 elements. Fig. 2 shows the arrangement of control points for constructing a spline surface in the shape of a torus: .. figure:: ../../pictures/M.5.2.2.png :width: 12cm :align: center Fig. 2 Fig. 3 shows the spline surface in the shape of a torus constructed on the above control points: .. figure:: ../../pictures/M.5.2.3.png :width: 12cm :align: center Fig. 3 Below there is an example in the C++ programming language that implements construction of a spline surface in the shape of a torus by this function (the center of the torus coincides with the origin of the global coordinate system, and the torus axis is directed along the global Z-axis): .. code-block:: cpp void AddTorusPoints( double r, double z, SArray & pointList, double w, SArray & weightList ) { MbCartPoint3D p( r, 0.0, z ); MbVector3D toX( 1.0, 0.0, 0.0 ), toY( 0.0, 1.0, 0.0 ); double wI( w ), wA = w * ::cos( M_PI_4 ); pointList.Add( p ); weightList.Add( wI ); p.Add( toY, r ); pointList.Add( p ); weightList.Add( wA ); p.Add( toX,-r ); pointList.Add( p ); weightList.Add( wI ); p.Add( toX,-r ); pointList.Add( p ); weightList.Add( wA ); p.Add( toY,-r ); pointList.Add( p ); weightList.Add( wI ); p.Add( toY,-r ); pointList.Add( p ); weightList.Add( wA ); p.Add( toX, r ); pointList.Add( p ); weightList.Add( wI ); p.Add( toX, r ); pointList.Add( p ); weightList.Add( wA ); } void GetTorusPoints( double majorR, double minorR, SArray & pointList, SArray & weightList ) { double zLavel( 0.0 ); double w0( 1.0 ), wA = ::cos( M_PI_4 ); ::AddTorusPoints( majorR - minorR, zLavel, pointList, w0, weightList ); ::AddTorusPoints( majorR - minorR,-minorR, pointList, wA, weightList ); ::AddTorusPoints( majorR ,-minorR, pointList, w0, weightList ); ::AddTorusPoints( majorR + minorR,-minorR, pointList, wA, weightList ); ::AddTorusPoints( majorR + minorR, zLavel, pointList, w0, weightList ); ::AddTorusPoints( majorR + minorR, minorR, pointList, wA, weightList ); ::AddTorusPoints( majorR , minorR, pointList, w0, weightList ); ::AddTorusPoints( majorR - minorR, minorR, pointList, wA, weightList ); } void GetTorusKnots( double tBeg, double tEnd, SArray & knots ) { double dt = ( tEnd - tBeg ) / 4.0; double t = tBeg - dt; knots.Add( t ); t = tBeg; knots.Add( t ); knots.Add( t ); t += dt; knots.Add( t ); knots.Add( t ); t += dt; knots.Add( t ); knots.Add( t ); t += dt; knots.Add( t ); knots.Add( t ); t = tEnd; knots.Add( t ); knots.Add( t ); t += dt; knots.Add( t ); knots.Add( t ); } MbSurface * CreateTorusSurface( double majorR, double minorR ) { MbSurface * result( NULL ); MbResultType res( rt_Error ); if ( majorR > METRIC_NEAR && majorR > minorR - EPSILON ) { SArray pointList( 64, 1 ); SArray weightList( 64, 1 ); SArray uKnotList( 13, 1 ); SArray vKnotList( 13, 1 ); size_t uDegree( 3 ), vDegree( 3 ); size_t uCount( 8 ), vCount( 8 ); bool uClosed( true ), vClosed( true ); ::GetTorusPoints( majorR, minorR, pointList, weightList ); ::GetTorusKnots( 0.0, 4.0, uKnotList ); ::GetTorusKnots( -2.0, 2.0, vKnotList ); res = ::SplineSurface( pointList, weightList, uCount, vCount, uDegree, uKnotList, uClosed, vDegree, vKnotList, vClosed, result ); } return ( res == rt_Success ) ? result : NULL; } The function .. code-block:: cpp MbResultType NurbsSurface( const MbSurface & surface, VERSION version, MbSurface *& result ); constructs a NURBS copy of a given surface. The input parameters of the function are: - **surface** is the source surface; - **version** is the construction version. The output parameter of the function is the constructed surface **result**. If successful, the function returns :code:`rt_Success`; otherwise, it returns an error code from the :ref:`MbResultType ` enumeration. The function is declared in the *action_surface.h* file. This function constructs a NURBS surface whose shape reproduces the shape of the source surface. The NURBS surface is described in subsection :ref:`NURBS Surface MbSplineSurface `. For most surface types the NURBS copy coincides in shape completely with the source surface. If it is impossible to reproduce the shape of the source surface exactly, the NURBS copy approximates the source surface. If the source surface is a surface with arbitrary borders :code:`MbCurveBoundedSurface`, which is described in subsection :ref:`Surface with Arbitrary Borders MbCurveBoundedSurface `, this function constructs a surface with arbitrary borders whose base surface is a NURBS copy of the base surface of the source surface. In the test application test.exe, construction of a NURBS surface is performed by the menu command «Create → Surface → Based on points → NURBS».