.. role:: blue :class: blue Скругление вершин и рёбер тела =============================== .. _Rounding-off_Body_Edges: .. версия ядра: 118044 Функция .. code-block:: cpp MbResultType FilletSolid( MbSolid & solid, MbeCopyMode sameShell, const MbShellFilletValues & filletParams, c3d::SolidSPtr & result, IProgressIndicator * progInd = nullptr ); выполняет замену указанных рёбер исходного тела гранями, гладко сопрягающими смежные грани указанных рёбер. В поперечном сечении сопрягающие грани могут иметь форму дуги окружности, эллипса, гиперболы, параболы. Способы скругления ребер тела: - скругление указанных рёбер тела постоянным радиусом; - скругление вершин и примыкающих к ним рёбер тела постоянным радиусом (в вершинах должно стыковаться три ребра); - скругление указанных ребер тела переменным радиусом, задаваемым :blue:`MbEdgeFunction.function`. Параметры поперечного сечения могут изменяться по заданному закону. Способ построения скругления определяется набором параметров в объекте **filletParams**. Входными параметрами функции являются: - **solid** -- исходное тело, ребра которого подлежат обработке; - **sameShell** -- режим копирования исходного тела; - **filletParams** -- параметры построения. Выходным параметром функции является построенное тело **result**. Функция возвращает код результата операции из перечисления :blue:`MbResultType`. Функция объявлена в файле *action_solid.h*. Скругление ребер постоянным радиусом -------------------------------------- .. _Rounding-off_Body_Edges_by_Constant_Radius: При скруглении ребер постоянным радиусом для инициализации объектов **filletParams** с параметрами операции в классе :blue:`MbShellFilletValues` определен следующий конструктор: .. code-block:: cpp MbShellFilletValues( c3d::EdgesSPtrVector initCurves, c3d::FacesSPtrVector & initBounds, const SmoothValues & params, const MbSNameMaker & names ) : MbShellChamferParams( initCurves, params, names ) , _initBounds( initBounds ) {} где - **initCurves** -- множество скругляемых ребер тела; - **initBounds** -- множество граней для обрезки торцов; - **params** -- параметры скругления рёбер; - **names** -- именователь. Параметр построения скруглений *params* содержит информацию о форме и способе сопряжения смежных граней обрабатываемых ребер, рис. 1. Класс :blue:`SmoothValues` описан в файле *op_shell_parameter.h*. .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.1.png :width: 8cm :align: center Рис. 1 - **distance1** -- радиус кривизны на первой поверхности; - **distance2** -- радиус кривизны на второй поверхности; - **conic** -- коэффициент формы поверхности сопряжения, принимает значения 0, 0.05...0.95 (0 -- дуга окружности или эллипса); - **begLength** -- расстояние от начала скругления до точки остановки (UNDEFINED_DBL -- остановки нет); - **endLength** -- расстояние от конца скругления до точки остановки (UNDEFINED_DBL -- остановки нет); - **form** -- тип сопряжения (скругления) из перечисления :blue:`MbeSmoothForm`; - **smoothCorner** -- способ обработки углов стыковки трёх рёбер; - **prolong** -- флаг продолжения скругления по касательным рёбрам; - **keepCant** -- автоопределение сохранения кромки (*ts_neutral*), сохранения поверхности (*ts_negative*), сохранения кромки (*ts_positive*); - **strict** -- флаг строгости построения: при *false* скруглить хотя бы то, что возможно; - **equable** -- флаг вставки тороидальной поверхности в углах сочленения поверхности сопряжения (для штамповки листового тела); - **vector1** -- вектор нормали к плоскости, по которой выполняется усечение скругления в начале цепочки; - **vector2** -- вектор нормали к плоскости, по которой выполняется усечение скругления в конце цепочки. Типом скругления управляет параметр **form**. Для скругления ребер используются значения параметра **form** равные *st_Ellipse*, *st_Fillet* и *st_Span*. При значении **form** = *st_Fillet* функция строит поверхность скругления с заданными радиусами, которые определяются параметрами **distance1** и **distance2**. На рис. 2 приведено скругление с заданными радиусами ребра, соединяющего две цилиндрические поверхности: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.2.png :width: 12cm :align: center Рис. 2 При **distance1** = **distance2** и **conic** = 0 поверхность скругления строится путем движения сферы, касающейся двух смежных для скругляемого ребра граней. Опорные края грани сопряжения проходят по точкам касания сферы и соответствующей смежной грани. Поперечное сечение грани сопряжения представляет собой дугу окружности. На рис. 3 приведено скругление с заданными одинаковыми радиусами ребра, соединяющего две цилиндрические поверхности: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.3.png :width: 12cm :align: center Рис. 3 Коэффициент **conic** управляет формой поверхности скругления. При **conic** = 0 (макрос \_ARC\_) сечение поверхности сопряжения имеет форму дуги окружности или эллипса с заданными радиусами. Кроме нулевого значения коэффициент формы может принимать значения от 0.05 до 0.95. При **conic** = 0.5 поперечное сечение грани скругления представляет собой дугу параболы. При **conic** < 0.5 поперечное сечение грани скругления представляет собой дугу эллипса. При **conic** > 0.5 поперечное сечение грани скругления представляет собой дугу гиперболы. На рис. 4, 5 приведены скругления одинаковыми радиусами ребра, соединяющего две цилиндрические поверхности, с разными коэффициентами формы: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.4.png :width: 12cm :align: center Рис. 4 .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.5.png :width: 12cm :align: center Рис. 5 При значении **form** = *st_Span* функция строит поверхность скругления с заданной хордой. Параметры **distance1** и **distance2** равны и определяют расстояние между опорными краями грани сопряжения. Поперечное сечение грани скругления представляет собой дугу окружности. В общем случае в каждом поперечном сечении грани скругления радиус дуги различный, а параметры **distance1** и **distance2** равны хорде дуги окружности. На рис. 6 приведено скругление с заданной хордой ребра, соединяющего две цилиндрические поверхности: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.6.png :width: 12cm :align: center Рис. 6 На рис. 7 приведено скругление с заданной хордой ребра, соединяющего две цилиндрические поверхности, с ненулевым коэффициентом формы: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.7.png :width: 12cm :align: center Рис. 7 На рис. 8 приведен пример остановки скругления на расстоянии **begLength** от начальной вершины и на расстоянии **endLength** от конечной вершины обрабатываемого ребра. Если не требуется останавливать сопряжение, то расстояния **begLength** и **endLength** должны принимать значение *UNDEFINED_DBL*. По умолчанию остановка скругления выполняется гранями, перпендикулярными скругляемому ребру. Можно переопределить поведение остановки скругления, используя вектор **vector1** как нормаль останавливающей грани в начале сопряжения и вектор **vector2** как нормаль останавливающей грани в конце сопряжения. .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.8.png :width: 12cm :align: center Рис. 8 На примере тела, приведенного на рис. 9, продемонстрируем работу флагов *prolong* и *keepCant* при скруглении выделенного на рисунке ребра. .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.9.png :width: 12cm :align: center Рис. 9 Флаг *prolong* указывает на то, какие ребра тела должны быть обработаны. Если *prolong* = *false*, то обработке подлежат только те ребра, которые указаны в контейнере **initCurves**, рис. 10. .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.10.png :width: 12cm :align: center Рис. 10 Если *prolong* = true, то обработке подлежат ребра, указанные в контейнере **initCurves**, а также ребра, гладко стыкующиеся с ними, рис. 11: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.11.png :width: 12cm :align: center Рис. 11 Параметр **keepCant** управляет обработкой ситуаций, когда опорные края грани сопряжения выходят за границу смежной грани. Если *keepCant* = *ts_negative*, то при выходе опорного края грани сопряжения за границу смежной грани через острое ребро грань сопряжения не меняет своей формы, а «подрезается» соседней гранью, как приведено на рис. 11. Если *keepCant* = *ts_positive*, то при выходе опорного края грани сопряжения за границу смежной грани через острое ребро грань сопряжения меняет свою форму и проходит опорным краем по границе, сохраняя ее неизменной, как приведено на рис. 12: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.12.png :width: 12cm :align: center Рис. 12 Если *keepCant* = *ts_neutral*, то при выходе опорного края грани сопряжения за границу смежной грани через гладкое ребро грань сопряжения заменяет смежную грань на соседнюю, изменяя форму на данном участке, рис. 13: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.13.png :width: 12cm :align: center Рис. 13 На рис. 14 приведено скругление четырех ребер, выполненное одним вызовом функции с флагом **equable** = *false* (в углах сочленения тороидальная поверхность отсутствует): .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.14.png :width: 12cm :align: center Рис. 14 На рис. 15 приведено скругление четырех ребер, выполненное одним вызовом функции с флагом **equable** = *true*, указывающим на необходимость вставлять тороидальную поверхность в углы сочленения поверхностей сопряжения: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.15.png :width: 12cm :align: center Рис. 15 При построении скругления трех ребер, стыкующихся в одной вершине, параметр **smoothCorner** определяет способ обработки скругления чемоданных углов. Если **smoothCorner** = *ec_pointed*, то обработка углов, в которых стыкуются три ребра одинаковой выпуклости, отсутствует (рис. 16): .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.16.png :width: 12cm :align: center Рис. 16 Если **smoothCorner** = *ec_uniform*, то углы, в которых стыкуются три ребра различной выпуклости, обрабатываются одинаковым образом -- если в точке стыкуются два выпуклых (вогнутых) и одно вогнутое (выпуклое) ребро, то первыми обрабатываются два выпуклых (вогнутых) ребра (рис. 17): .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.17.png :width: 12cm :align: center Рис. 17 Если **smoothCorner** = *ec_sharp*, то углы, в которых стыкуются три ребра различной выпуклости, обрабатываются одинаковым образом, как показано на рис. 18. Если в точке стыкуются два выпуклых (вогнутых) и одно вогнутое (выпуклое) ребро, то первыми обрабатываются выпуклые (вогнутые) ребра. .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.18.png :width: 12cm :align: center Рис. 18 Если **smoothCorner** = *ec_either*, то углы, в которых стыкуются три ребра различной выпуклости, могут быть обработаны разным образом -- стыкующиеся в одной точке три ребра обрабатываются в порядке внутренней нумерации ребер без учета выпуклости и вогнутости. В неоднозначной ситуации на торцах грани сопряжения может быть задействован параметр **initBounds** с гранями тела **solid**, которые следует использовать для обрезки граней сопряжения. Пример использования параметра **initBounds** приведен на рис. 19 и 20: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.19.png :width: 12cm :align: center Рис. 19 .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.20.png :width: 12cm :align: center Рис. 20 Параметр **initBounds** может использоваться для остановки граней сопряжения в начале и конце. При этом грани, определяемые параметром **initBounds**, должны принадлежать исходному телу **solid**. На рис. 21 приведена модель, у которой требуется построить скругления указанных ребер, полностью охватывающие отверстие и выступ: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.21.png :width: 12cm :align: center Рис. 21 Результат построения скругления с обходом препятствий приведен на рис. 22: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.22.png :width: 12cm :align: center Рис. 22 На рис. 23 приведен пример одновременного скругления группы из шести ребер, стыкующихся в общей вершине: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.23.png :width: 12cm :align: center Рис. 23 На рис. 24 приведен пример скругления нескольких групп из четырех ребер, стыкующихся в общих вершинах. Особенностью скругления служит то обстоятельство, что группы связаны между собой и могут обрабатываться только одновременно. Исходное тело, для показанного на рис. тела, получено путем вычитания из куба четырех цилиндров, оси которых совпадают с диагоналями куба. .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.10.24.png :width: 12cm :align: center Рис. 24 Когда в методах построения скругления параметры *distance1* и *distance2* не равны и для обработки заданы несколько ребер, то трудно разобраться, что чему соответствует. В такой ситуации предлагается использовать вспомогательные методы: :blue:`SmoothPhantom`\(), :blue:`SmoothSequence`\(), :blue:`SmoothPositionData`\(), объявленные в файле *action_phantom.h*. Функция :blue:`SmoothPhantom`\() строит упрощенные поверхности для имитации будущих скруглений. Функция :blue:`SmoothSequence`\() строит последовательности ребер, к которым по желанию могут быть добавлены гладко стыкующиеся ребра, обрабатываемые совместно. Функция :blue:`SmoothPositionData`\() вычисляет тройку опорных точек скругления, которые позволяют оценить заданные параметры скругления. Обычно с помощью указанных функций рисуется некий фантом, по которому можно понять, что получится в результате операции, и дается возможность поменять параметры при необходимости. Перед построением скруглений обрабатываемые ребра сортируются, при необходимости или по требованию к ним добавляются гладко стыкующиеся ребра, и из ребер создаются последовательности гладко стыкующихся ребер. Параметры **distance1** и **distance2** привязаны к первой и второй поверхностям и, соответственно, к кривой пересечения первого ребра в последовательности гладко стыкующихся ребер. Поверхности можно получить функциями кривой пересечения :blue:`GetCurveOneSurface`\() и :blue:`GetCurveTwoSurface`\(). По **distance1** и **distance2** первого ребра определяются параметры для остальных ребер каждой последовательности. Так, если для первого ребра указатель :blue:`edge`\→\ :blue:`GetIntersectionCurve`\().\ :blue:`GetSurfaceOne`\() равен указателю **edge**\→\ :blue:`GetFacePlus`\()→\ :blue:`GetSurface`\().\ :blue:`GetSurface`\(), то при построении скругления **distance1** будет соответствовать радиусу для грани **facePlus**, а **distance2** будет соответствовать радиусу для грани **faceMinus** первого ребра последовательности. При построении скругления ребер рассматриваемая функция добавляет в журнал построенного тела строитель :blue:`MbFilletSolid`, который объявлен в файле *cr_fillet_solid.h*. В тестовом приложении *test.exe* обработка ребер тела выполняется командами меню «Создать→Тело→Обработкой ребер→Скругление по радиусу», «Создать→Тело→Обработкой ребер→Скругление по хорде». Скругление ребер переменным радиусом -------------------------------------- Функция аналогична описанной в предыдущем параграфе, и отличается от нее параметром **initFunctions**. При скруглении ребер сопрягающие грани в поперечном сечении могут иметь форму дуги окружности переменного радиуса. При скруглении ребер переменным радиусом для инициализации объектов **filletParams** с параметрами операции в классе :blue:`MbShellFilletValues` определен следующий конструктор: .. code-block:: cpp MbShellFilletValues( const std::vector & initFunctions, c3d::FacesSPtrVector & initBounds, const MbSNameMaker & names, const SmoothValues & params ) : MbShellChamferParams( c3d::EdgesSPtrVector(), params, names ) , _initFunctions( initFunctions ) , _initBounds( initBounds ) {} где - **initFunctions** -- множество скругляемых ребер тела с функциями изменения радиуса; - **initBounds** -- множество граней для обрезки торцов; - **params** -- параметры скругления рёбер; - **names** -- именователь. Параметр **initFunctions** содержит обрабатываемые ребра тела **solid** и функции изменения радиуса вдоль ребра. Каждый элемент множества **initFunctions** состоит из указателя на ребро и указателя на скалярную функцию, на значения которой будут умножены радиусы скругления **distance1** и **distance2**, рис. 25: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.11.1.png :width: 9cm :align: center Рис. 25 Для скругления ребер переменного радиуса используется значение параметра **form** равное *st_Fillet*. Для каждой точки обрабатываемого ребра **initFunctions**\[i\].\ **initFunctions**\→Point(*t*, **point**) радиусы поверхности скругления равны параметрам **distance1** и **distance2**, умноженным на значение функции ребра **initFunctions**\[i\].function\→Value(*t*). На рис. 26 приведено скругление с переменными радиусами ребра прямоугольной призмы. При **distance1** = **distance2** и **conic** = 0 поверхность скругления строится путем движения сферы переменного радиуса, касающейся двух смежных для скругляемого ребра граней. Опорные края грани сопряжения проходят по точкам касания сферы и соответствующей смежной грани. Поперечное сечение грани сопряжения представляет собой дугу окружности. .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.11.2.png :width: 11cm :align: center Рис. 26 На рис. 27 приведено эллиптическое скругление с переменными радиусами ребра прямоугольной призмы: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.11.3.png :width: 11cm :align: center Рис. 27 На рис. 28, 29 приведены скругления с переменными радиусами ребра прямоугольной призмы с разными коэффициентами формы **conic**: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.11.4.png :width: 12cm :align: center Рис. 28 .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.11.5.png :width: 12cm :align: center Рис. 29 На рис. 30 приведен пример остановки скругления на расстоянии **begLength** от начальной вершины и на расстоянии **endLength** от конечной вершины обрабатываемого ребра. При задании параметров остановки скругления метод изменения радиусов скругления задается для всего ребра. Если не требуется останавливать сопряжение, то расстояния **begLength** и **endLength** должны принимать значение *UNDEFINED_DBL*. .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.11.6.png :width: 12cm :align: center Рис. 30 Для ребер продолжения скругления функция изменения радиуса принимает константное значение, равное значению функции на краю предыдущего гладко стыкующегося ребра. На рис. 31 приведено исходное тело, ребра, подлежащие скруглению, и функция изменения радиуса для указанных ребер: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.11.7.png :width: 12cm :align: center Рис. 31 На рис. 32 приведен результат работы функции для исходного тела. На рисунке видно, что на краях функция изменения радиуса была подобрана так, чтобы обеспечить гладкое сопряжение с соседней гранью скругления: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/M.2.11.8.png :width: 12cm :align: center Рис. 32 В тестовом приложении *Test.exe* обработка ребер тела переменным радиусом выполняется командой меню «Создать→Тело→Обработкой ребер→Скругление переменное». Скругление вершин и примыкающих к ним рёбер постоянным радиусом ----------------------------------------------------------------- При скруглении вершин и примыкающих к ним рёбер постоянным радиусом для инициализации объектов **filletParams** с параметрами операции в классе :blue:`MbShellFilletValues` определен следующий конструктор: .. code-block:: cpp MbShellFilletValues( c3d::EdgesSPtrVector & initCurves, c3d::FacesSPtrVector & initBounds, c3d::VerticesSPtrVector & initVertices, const CornerValues & cornerData, const SmoothValues & params, const MbSNameMaker & names ) : MbShellChamferParams( initCurves, params, names ) , _initBounds ( initBounds ) , _initVertices( initVertices ) , _cornerData ( cornerData ) {} где - **initCurves** -- множество скругляемых ребер тела; - **initBounds** -- множество граней для обрезки торцов; - **initVertices** -- множество скругляемых вершин; - **cornerData** -- параметры скругления вершин; - **params** -- параметры скругления рёбер; - **names** -- именователь. Параметр построения скруглений **params** содержит информацию о форме и способе сопряжения смежных граней обрабатываемых ребер (см. :ref:`Скругление ребер постоянным радиусом `). Параметры скругления вершины **cornerData**, в которой стыкуются три ребра, содержат информацию, необходимую для выполнения операции, рис. 33. Класс :blue:`CornerValues` описан в файле *op_shell_parameter.h*. .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/CornerValues.png :width: 9cm :align: center Рис. 33 - **radius0** -- радиус сферы в вершине; - **radius1** -- радиус первого ребра вершины; - **radius2** -- радиус второго ребра вершины; - **radius3** -- радиус третьего ребра вершины; - **cornerForm** -- способ скругления вершины стыковки трёх рёбер; - **additive** -- сдвиг в нумерации рёбер вершины (добавка к номеру ребра). Типом скругления вершины управляет параметр **cornerForm**. Для скругления вершин используются следующие значения параметра **cornerForm**: *ef_sphere* -- скругление вершины сферической поверхностью; *ef_smart* -- скругление вершины гладкой поверхностью; *ef_delta* -- скругление вершины треугольной поверхностью; *ef_elbow1* -- скругление вершины четырёхугольной поверхностью (четвёртая сторона располагается напротив первого ребра вершины); *ef_elbow2* -- скругление вершины четырёхугольной поверхностью (четвёртая сторона располагается напротив второго ребра вершины); *ef_elbow3* -- скругление вершины четырёхугольной поверхностью (четвёртая сторона располагается напротив третьего ребра вершины). При значении **cornerForm** = *ef_sphere* вершины, в которых стыкуются три ребра различной выпуклости, скругляются сферической поверхностью как показано на рис. 34: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/3.8.1.png :width: 12cm :align: center Рис. 34 При значении **cornerForm** = *ef_smart* вершины, в которых стыкуются три ребра различной выпуклости, скругляются гладкой поверхностью как показано на рис. 35: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/3.8.2.png :width: 12cm :align: center Рис. 35 При значении **cornerForm** = *ef_delta* вершины, в которых стыкуются три ребра различной выпуклости, скругляются треугольной поверхностью как показано на рис. 36: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/3.8.3.png :width: 12cm :align: center Рис. 36 При значении **cornerForm** = *ef_elbow2* вершины, в которых стыкуются три ребра различной выпуклости, скругляются четырёхугольной поверхностью с расположением четвёртой стороны напротив второго ребра вершины как показано на рис. 37: .. figure:: /MODELER/OPERATIONS_ON_BODIES/pictures/3.8.5.png :width: 12cm :align: center Рис. 37 В тестовом приложении *test.exe* скругление вершин и примыкающих к ним рёбер постоянным радиусом выполняется командами меню «Создать→Тело→Обработкой вершин→Скруглением вершин».