.. role:: code :class: code Построение деформируемого тела =============================== .. _Constructing_a_Deformable_Body: .. версия ядра: 118061 Построение деформируемого тела выполняется в четыре последовательных этапа, каждый из которых реализуется отдельной функцией. Цель – получить тело **result**, в котором выбранные грани исходного тела **solid** заменены на деформируемые грани. Вызов функции последующего этапа без успешного завершения предыдущего приводит к неопределённому поведению. Этап 1. Подготовка граней к деформации ---------------------------------------- На первом этапе задают объект параметров типа **NurbsValues** и вызывают одну из функций :code:`ModifiedNurbsItem`\() – либо вариант с массивом граней **faces**, либо вариант с одной гранью **face**. В результате получают тело **result**, в котором указанные грани исходного тела **solid** заменены на NURBS-поверхности, пригодные для дальнейшей модификации. После успешного выполнения данного этапа следует перейти к **этапу 2** – вызову функции :code:`GetControlSurface`\(). Функция .. code-block:: cpp MbResultType ModifiedNurbsItem( MbSolid & solid, MbeCopyMode sameShell, const NurbsValues & p, const RPArray & faces, const MbSNameMaker & names, MbSolid *& result ) выполняет замену выбранных граней тела деформируемыми гранями для последующего редактирования. Входными параметрами функции являются: - **solid** -- исходное тело; - **sameShell** -- вариант копирования исходного тела; - **p** -- объект с параметрами преобразования; - **faces** -- заменяемые грани тела; - **names** -- именователь операции. Выходным параметром функции является построенное тело **result**. При удачной работе функция возвращает :code:`rt_Success`, в противном случае функция возвращает код ошибки из перечисления :ref:`MbResultType ` (см. *mb_operation_result.h*). Функция объявлена в файле *action_direct.h*. При создании объекта **p** с параметрами модификации используется следующий конструктор параметров (см. *op_shell_parameter.h*): - **ud, vd** -- порядок NURBS-копии по u и по v; - **uc, vc** -- количество контрольных точек по u и по v; - **umin, umax, vmin, vmax** -- диапазоны параметров по u и v для деформирования грани; - **uapprox, vapprox** -- флаги возможного построения приближенной поверхности, а не точной. .. code-block:: cpp NurbsValues( size_t ud, size_t uc, double umin, double umax, bool uapprox, size_t vd, size_t vc, double vmin, double vmax, bool vapprox ) : uParameters( ud, uc, umin, umax, uapprox ) , vParameters( vd, vc, vmin, vmax, vapprox ) {} Объект **p** хранит два набора параметров типа :code:`MbNurbsParameters`: **uParameters** и **vParameters** необходимые для построения NURBS-поверхностей. Параметры **ud**, **uc**, **umin**, **umax**, **uapprox** задают поля **uParameters**, а параметры **vd**, **vc**, **vmin**, **vmax**, **vapprox** -- поля **vParameters**. Рассматриваемая функция выполняет копирование тела **solid** (в зависимости от параметра **sameShell**) и подготовку копии тела для дальнейшего деформирования указанных граней исходного тела. Параметр **solid** содержит исходное тело, в котором указанные грани будут заменены на деформируемые грани на базе NURBS-поверхностей. Параметр **sameShell** управляет передачей граней, рёбер и вершин от исходного тела **solid** построенному телу **result** и может принимать одно из четырех значений: - *cm_Same* = 0 (тело не копируется); - *cm_KeepHistory* (исходная оболочка и её копия имеют общие базовые поверхности, вершины и неизменённые операцией грани); - *cm_KeepSurface* (исходное тело и его копия имеют общие базовые поверхности); - *cm_Copy* (исходное тело и его копия не имеют общих данных). Перечисление :code:`MbeCopyMode` объявлено в файле *mb_enum.h* и подробно описано в параграфе :ref:`Копирование множества граней MbFaceShell `. Параметр **faces** содержит множество граней тела **solid**, которые будут заменены на деформируемые грани на базе NURBS-поверхностей в построенном теле **result**. Параметр **names** используется для именования новых граней, рёбер, вершин и версионирования операции. Функция .. code-block:: cpp MbResultType ModifiedNurbsItem( MbSolid & solid, MbeCopyMode sameShell, const NurbsValues & params, const MbFace & face, const MbSNameMaker & names, MbSolid *& result ) выполняет замену одной грани тела деформируемой гранью для последующего редактирования. Данная функция отличается от вышеописанной только четвёртым параметром, который содержит не множество граней, а одну заменяемую грань **face**. Функция объявлена в файле *action_direct.h*. Построенное тело **result** внешне может быть похожим на исходное тело **solid**, но в отличие от исходного тела имеет NURBS-поверхности, доступные для модификации. На рис. 1 слева приведено исходное цилиндрическое тело **solid**, боковая грань которого является цилиндром :code:`MbCylinderSurface`, справа приведено тело **result** с боковой гранью, базирующейся на NURBS-поверхности. Контрольные точки NURBS-поверхности также приведены на рисунке справа: .. figure:: ../../pictures/M.6.3.2.png :width: 18cm :align: center Рис. 1 Функции :code:`ModifiedNurbsItem`\() добавляют в журнал построенного тела строитель :code:`MbModifiedNurbsItem`, который содержит все необходимые данные для выполнения операции. Строитель :code:`MbModifiedNurbsItem` объявлен в файле *cr_modified_nurbs_.h*. Этап 2. Получение базовой NURBS-поверхности грани ---------------------------------------------------- На втором этапе, при необходимости, для выбранной грани **face** тела **result** вызывают функцию :code:`GetControlSurface`\() и получают копию базовой NURBS-поверхности грани, которую можно изменять независимо от тела. После успешного выполнения данного этапа следует перейти к **этапу 3** – вызову функции :code:`FaceControlPoints`\(). Функция .. code-block:: cpp MbSurface * GetControlSurface( const MbFace & face ) выполняет построение деформируемой NURBS-поверхности на базе исходной грани **face** для дальнейшего редактирования. Входным параметром функции является исходная грань **face**. Функция объявлена в файле *action_direct.h*. Функция возвращает ненулевой указатель на поверхность, если грань **face** базируется на NURBS-поверхности. Это требование будет выполняться после успешной работы функций :code:`ModifiedNurbsItem`\(). Функция возвращает указатель на копию базовой поверхности грани **face**, а не на саму базовую поверхность грани. Далее у возвращаемой поверхности можно модифицировать множество контрольных точек и их веса. Этап 3. Получение контрольных точек грани --------------------------------------------- На третьем этапе, если требуется управлять формой грани через её контрольные точки, для грани **face** вызывают функцию :code:`FaceControlPoints`\() и получают матрицу контрольных точек и их весов. Пользователь изменяет координаты контрольных точек и/или их веса в соответствии с требуемой деформацией. После успешного выполнения данного этапа следует перейти к **этапу 4** -- вызову функции :code:`NurbsModification`\(). Функция .. code-block:: cpp MbResultType FaceControlPoints( const MbFace & face, Array2 & controlPoints, Array2 & result ) выдаёт множество контрольных точек поверхности грани и множество их весов. Входным параметром функции является исходная грань **face**. Выходными параметрами функции являются: - **controlPoints** -- контрольные точки грани; - **result** -- веса контрольных точек. Функция объявлена в файле *action_direct.h*. Функция возвращает :code:`rt_Success`, если грань **face** базируется на NURBS-поверхности, в противном случае возвращается код ошибки из перечисления :ref:`MbResultType ` (см. *mb_operation_result.h*). Изменяя положение контрольных точек **controlPoints** и изменяя веса **result** контрольных точек, можно менять форму поверхности. Рассматриваемую функцию следует использовать после успешной работы функций :code:`ModifiedNurbsItem`\(), описанных выше. Контрольные точки **controlPoints** передаются в виде прямоугольной матрицы, строки которой соответствуют первому параметру NURBS-поверхности, а столбцы соответствуют второму параметру NURBS-поверхности. То есть точки, лежащие в одной строке прямоугольной матрицы **controlPoints**, расположены вдоль координатной линии поверхности с фиксированным вторым параметром NURBS-поверхности, а точки, лежащие в одном столбце прямоугольной матрицы **controlPoints**, расположены вдоль координатной линии поверхности с фиксированным первым параметром NURBS-поверхности. На рис. 2 приведены контрольные точки на фоне координатных линий поверхности: .. figure:: ../../pictures/M.6.3.4.png :width: 15cm :align: center Рис. 2 Прямоугольная матрица **result** весов соответствует прямоугольной матрице контрольных точек **controlPoints**. На рис. 3 слева приведена грань **face** и контрольные точки **controlPoints** ее поверхности, справа приведены отредактированные контрольные точки **controlPoints** для последующей модификации грани **face**: .. figure:: ../../pictures/M.6.3.5.png :width: 18cm :align: center Рис. 3 Этап 4. Применение деформации к телу ---------------------------------------- На четвёртом этапе деформацию применяют к телу с помощью одной из функций :code:`NurbsModification`\(). В варианте с поверхностью передают модифицированную поверхность **faceSurface** и неподвижные узлы. В варианте с контрольными точками передают изменённые контрольные точки, веса и узлы. В обоих случаях на выходе получают модифицированное тело **result** с изменённой формой выбранной грани. Функция .. code-block:: cpp MbResultType NurbsModification( MbSolid & solid, MbeCopyMode sameShell, MbFace * face, MbSurface & faceSurface, Array2 & fixedPoints, const MbSNameMaker & names, MbSolid *& result ) выполняет деформирование заданной грани исходного тела путём подстановки присланной поверхности в изменяемую грань. Входными параметрами функции являются: - **solid** -- исходное тело; - **sameShell** -- вариант копирования исходного тела; - **face** -- изменяемая грань тела; - **faceSurface** -- новая NURBS-поверхность для грани; - **fixedPoints** -- неподвижные узлы (если указатель **fixedPoints** равен *nullptr*, все контрольные точки считаются подвижными); - **names** -- именователь операции. Выходным параметром функции является построенное модифицированное тело **result**. При удачной работе функция возвращает :code:`rt_Success`, в противном случае возвращается код ошибки из перечисления :ref:`MbResultType ` (см. *mb_operation_result.h*). Функция объявлена в файле *action_direct.h*. Рассматриваемая функция копирует тело **solid** и подставляет присланную поверхность **faceSurface** в копию грани **face** тела **solid**. Поверхность **faceSurface** должна быть NURBS-поверхностью. Параметр **fixedPoints** представляет собой прямоугольную матрицу, строки и столбцы которой соответствуют строкам и столбцам матрицы контрольных точек NURBS-поверхности **faceSurface**. Элементы матрицы со значением *true* определяют неподвижные контрольные точки NURBS-поверхности. Функция .. code-block:: cpp MbResultType NurbsModification( MbSolid & solid, MbeCopyMode sameShell, MbFace * face, const Array2 & controlPoints, const Array2 & weights, Array2 * fixedPoints, const MbSNameMaker & names, MbSolid *& result ) выполняет деформирование указанной грани исходного тела по заданным контрольным точкам и их весам. Входными параметрами функции являются: - **solid** -- исходное тело; - **sameShell** -- вариант копирования исходного тела; - **face** -- изменяемая грань тела; - **controlPoints** -- заданные контрольные точки изменяемой грани; - **weights** -- веса контрольных точек; - **fixedPoints** -- неподвижные узлы (если указатель **fixedPoints** равен *nullptr*, все контрольные точки считаются подвижными); - **names** -- именователь операции. Выходным параметром функции является построенное тело **result**. При удачной работе функция возвращает :code:`rt_Success`, в противном случае возвращается код ошибки из перечисления :ref:`MbResultType ` (см. *mb_operation_result.h*). Функция объявлена в файле *action_direct.h*. Рассматриваемую функцию следует использовать после успешной работы функций :code:`ModifiedNurbsItem`\(), :code:`GetControlSurface`\() и :code:`FaceControlPoints`\(), описанных выше. Функции :code:`ModifiedNurbsItem`\() подготавливают грани для модификации. На рис. 4 приведено исходное цилиндрическое тело **solid**, боковая грань которого базируется на NURBS-поверхности, и у которой подлежат модификации контрольные точки. Также на рисунке приведено тело **result** с модифицированной боковой гранью, контрольные точки **controlPoints** которой приведены на рис. 3: .. figure:: ../../pictures/M.6.3.7.png :width: 18cm :align: center Рис. 4 Функции :code:`NurbsModification`\() добавляют в журнал построенного тела строитель :code:`MbNurbsModification`, который содержит все необходимые данные для выполнения операции. Строитель :code:`MbNurbsModification` объявлен в файле *cr_modified_nurbs_.h*.