.. role:: code :class: code Построение NURBS поверхности ============================= .. _NURBS_Surface_Construction: .. версия ядра: 118056 Функция .. 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 ); выполняет построение NURBS-поверхности на основе четырёх угловых точек и равномерной сетки контрольных точек. Входными параметрами функции являются: - **pUMinVMin** -- левая нижняя угловая точка поверхности; - **pUMaxVMin** -- правая нижняя угловая точка поверхности; - **pUMaxVMax** -- правая верхняя угловая точка поверхности; - **pUMinVMax** -- левая верхняя угловая точка поверхности; - **uCount** -- количество контрольных точек вдоль первого параметра (по горизонтали); - **vCount** -- количество контрольных точек вдоль второго параметра (по вертикали); - **uDegree** -- порядок B-сплайнов вдоль первого параметра; - **vDegree** -- порядок B-сплайнов вдоль второго параметра. Выходным параметром функции является построенная сплайновая поверхность **result**. При успешном завершении работы функция возвращает :code:`rt_Success`, в противном случае функция возвращает код ошибки из перечисления :ref:`MbResultType `. Функция объявлена в файле *action_surface.h*. Рассматриваемая функция строит NURBS-поверхность, контрольные точки которой расположены в узлах четырехугольной таблицы с **uCount** колонками и **vCount** строками. Порядок *B*-сплайнов поверхности по первому параметру равен **uDegree**, порядок *B*-сплайнов поверхности по второму параметру равен **vDegree**. Контрольные точки поверхности рассчитываются из условия равномерного расположения и совпадения угловых точек с точками **pUMinVMin**, **pUMaxVMin**, **pUMaxVMax**, **pUMinVMax**, рис. 1: .. figure:: ../../pictures/M.5.2.1.png :width: 15cm :align: center Рис. 1 Веса всех контрольных точек равны единице. Построенная поверхность предназначена для дальнейшей модификации. Для параметров функции должны выполняться равенства: **uCount** ≥ **uDegree** и **vCount** ≥ **vDegree**. NURBS-поверхность описана в параграфе :ref:`NURBS-поверхность MbSplineSurface `. Функция .. 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 ); выполняет построение NURBS поверхности по контрольным точкам и их весам. Входными параметрами функции являются: - **pointList** -- множество контрольных точек, условно расположенных в виде **vCount** строк по **uCount** точек в каждой строке; - **weightList** -- множество весов контрольных точек, согласованное с множеством контрольных точек; - **uCount** -- количество контрольных точек вдоль первого параметра (в каждой строке); - **vCount** -- количество контрольных точек вдоль второго параметра (количество строк); - **uDegree** -- порядок B-сплайнов вдоль первого параметра; - **uKnotList** -- узловой вектор первого параметра; - **uClosed** -- циклическая замкнутость поверхности по первому параметру; - **vDegree** -- порядок B-сплайнов вдоль второго параметра; - **vKnotList** -- узловой вектор второго параметра; - **vClosed** -- циклическая замкнутость поверхности по второму параметру. Выходным параметром функции является построенная поверхность **result**. При успешном завершении работы функция возвращает :code:`rt_Success`, в противном случае функция возвращает код ошибки из перечисления :ref:`MbResultType `. Функция объявлена в файле *action_surface.h*. Рассматриваемая функция строит NURBS-поверхность с контрольными точками **pointList**. Контрольные точки множества **pointList** будут разбиты на условные строки и столбцы. В каждой строке будет содержаться **uCount** контрольных точек из множества **pointList**, количество строк будет равно **vCount**. Таким образом множество **pointList** должно содержать **uCount**\ :sup:`.`\ **vCount** контрольных точек. Порядок *B*-сплайнов поверхности по первому параметру равен **uDegree**, порядок *B*-сплайнов поверхности по второму параметру равен **vDegree**. Для параметров функции должны выполняться равенства: **uCount** ≥ **uDegree** и **vCount** ≥ **vDegree**. NURBS-поверхность описана в параграфе :ref:`NURBS-поверхность MbSplineSurface `. Множества **weightList**, **uKnotList**, **vKnotList** могут быть пустыми. Если множество **weightList** пусто, то веса контрольных точек -- единичные. Если множества **uKnotList** или **vKnotList** пусты, то узловые векторы формируются автоматически. Если множество **weightList** не пусто, то оно должно быть согласовано с множеством контрольных точек **pointList**. Если множества **uKnotList** и **vKnotList** не пусты, то они должны содержать определенное количество элементов: для **uClosed** = *false* узловой вектор **uKnotList** должен содержать число элементов, равное **uCount** + **uDegree**; для **uClosed** = *true* узловой вектор **uKnotList** должен содержать число элементов, равное **uCount** + 2 · **uDegree** - 1; для **vClosed** = *false* узловой вектор **vKnotList** должен содержать число элементов, равное **vCount** + **vDegree**; для **vClosed** = *true* узловой вектор **vKnotList** должен содержать число элементов, равное **vCount** + 2 · **vDegree** - 1. На рис. 2 приведено расположение контрольных точек для построения сплайновой поверхности в форме тора: .. figure:: ../../pictures/M.5.2.2.png :width: 12cm :align: center Рис. 2 На рис. 3 приведена сплайновая поверхность в форме тора, построенная на указанных выше контрольных точках: .. figure:: ../../pictures/M.5.2.3.png :width: 12cm :align: center Рис. 3 Ниже приведен пример на языке программирования С++, реализующий построение сплайновой поверхности в форме тора рассматриваемой функцией (центр тора совпадает с началом глобальной системы координат, ось тора направлена по глобальной оси Z): .. 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; } Функция .. code-block:: cpp MbResultType NurbsSurface( const MbSurface & surface, VERSION version, MbSurface *& result ); выполняет построение NURBS-копии заданной поверхности. Входными параметрами функции являются: - **surface** -- исходная поверхность, - **version** -- версия построения. Выходным параметром функции является построенная поверхность **result**. При успешном завершении работы функция возвращает :code:`rt_Success`, в противном случае функция возвращает код ошибки из перечисления :ref:`MbResultType `. Функция объявлена в файле *action_surface.h*. Рассматриваемая функция строит NURBS-поверхность, форма которой копирует форму исходной поверхности. NURBS-поверхность описана в параграфе :ref:`NURBS-поверхность MbSplineSurface `. Для большинства типов поверхностей NURBS-копия по форме полностью совпадает с исходной поверхностью. В случае невозможности точно воспроизвести форму исходной поверхности NURBS-копия аппроксимирует исходную поверхность. Если исходная поверхность является поверхностью с произвольными границами :code:`MbCurveBoundedSurface`, описанной в параграфе :ref:`Поверхность с произвольными границами MbCurveBoundedSurface `, то рассматриваемая функция строит поверхность с произвольными границами, базовой поверхностью которой будет NURBS-копия базовой поверхности исходной поверхности. В тестовом приложении test.exe построение NURBS поверхности выполняется командой меню «Создать → Поверхность → По точкам → NURBS».