////////////////////////////////////////////////////////////////////////////////
/** 
  \file
  \brief \ru Методы преобразования полигональных геометрических объектов в объекты BRep.
         \en Functions for conversion of the polygonal geometric object to BRep objects. \~
  \details \ru Методы преобразования полигональных геометрических объектов в объекты BRep.
           \en Functions for conversion of the polygonal geometric object to BRep objects. \~ 

*/
////////////////////////////////////////////////////////////////////////////////

#ifndef __ACTION_B_SHAPER_H
#define __ACTION_B_SHAPER_H


#include <mb_cart_point.h>
#include <mb_cart_point3d.h>
#include <mesh.h>
#include <mb_enum.h>
#include <mb_operation_result.h>
#include <op_mesh_parameter.h>
#include <vector>


class  MATH_CLASS  MbPlacement3D;
class  MATH_CLASS  MbMesh;
class  MATH_CLASS  MbSurface;
class  MATH_CLASS  MbSNameMaker;
class  MATH_CLASS  MbFace;
class  MATH_CLASS  MbCollection;
struct MATH_CLASS  MbCurvature;


//------------------------------------------------------------------------------
/** \brief \ru Режим распознавания поверхностей.
           \en Surface reconstruction mode. \~
  \details \ru Режим распознавания поверхностей.
           \en Surface reconstruction mode. \~
  \ingroup Polygonal_Objects
*/
// ---
enum MbeSurfReconstructMode
{
  srm_All          = 0,           ///< \ru Строить все поверхности. \en Build all surfaces.
  srm_NoGrids      = 1,           ///< \ru Не строить поверхности на базе триангуляции. \en Not build surfaces based on triangulation.
  srm_CanonicOnly  = 2,           ///< \ru Строить только элементарные поверхности. \en Build elementary surfaces only.
  srm_Default      = srm_NoGrids  ///< \ru Режим по умолчанию. \en Default mode.
};


//------------------------------------------------------------------------------
/** \brief \ru Режим построения модели BRep.
           \en BRep creation mode. \~
  \details \ru Режим построения модели BRep.
           \en BRep creation mode. \~
  \ingroup Polygonal_Objects
*/
// ---
enum MbeCreateBRepMode
{
  cbm_Strict    = 0,          ///< \ru Соседние грани пересекаются по общей кривой. \en Adjancent faces have a common edge.
  cbm_Weak      = 1,          ///< \ru Все ребра каждой из граней - граничные. \en All edges of each face are a boundary edges.
  cbm_Default   = cbm_Strict  ///< \ru Режим по умолчанию. \en Default mode.
};

//------------------------------------------------------------------------------
/** \brief \ru Параметры построения оболочки тела по полигональной сетке.
           \en Parameters of BRep shell construction from polygonal mesh. \~
  \ingroup Polygonal_Objects
*/
// ---
class MATH_CLASS MbMeshProcessorValues {
public:

  /** \brief \ru Использовать относительную точность (true).
             \en Use relative tolerance (true). \~
    \details \ru При использовании относительной точности отклонение граней тела от сетки проверяется относительно размера модели.
             \en While use of relative tolerance distance from shell to mesh is checked relative to model size. \~
  */
  bool useRelativeTolerance;

  /** \brief \ru Флаг сглаживания краевых ребер.
             \en Smoothing flag of boundary edges. \~
    \details \ru Сглаживать краевые ребра результирующей оболочки или строить их кусочно-линейными.
             \en Smooth boundary edges of the resultant shell or build them piecewise linear. \~
  */
  bool smoothBoundaryEdges;

  /** \brief \ru Предельное значение угла между соседними внешними ребрами сетки в радианах.
             \en The treshold value of angle between two adjanced external edges of mesh (in radians). \~
    \details \ru Предельное значение угла между соседними ребрами сетки используется при построении граничных ребер оболочки: граничные ребра оболочки
                 будут разделяться в вершинах, где наименьший угол между соседними внешними ребрами сетки менее данного предельного.
             \en The treshold value of angle between two adjanced edges of mesh is used for building boundary edges of the shell:
                 boundary edge will be divied at the vertices at which minimum angle between two adjanced edges of mesh is less 
                 then a given treshold value. \~
  */
  double bAngle;

  /** \brief \ru Точность.
             \en Tolerance. \~
    \details \ru Точность работы метода: допустимое отклонение граней тела от вершин сетки.
             \en Tolerance: maximum distance from BRep faces to mesh vertices. \~
  */
  double tolerance;

  /** \brief \ru Режим распознавания поверхностей.
             \en Surface reconstruction mode. \~
  */
  MbeSurfReconstructMode surfReconstructMode;

    /** \brief \ru Режим построения модели BRep.
               \en BRep creation mode. \~
  */
  MbeCreateBRepMode brepCreationMode;

  /// \ru Конструктор по умолчанию. \en Default constructor.
  explicit MbMeshProcessorValues( bool                   useRelTol = true,
                                  bool                   smoothBoundary = true, 
                                  double                 tol = 0.01, 
                                  double                 angle = M_PI_2,
                                  MbeSurfReconstructMode reconMode = srm_Default,
                                  MbeCreateBRepMode      bMode = cbm_Default )
    : useRelativeTolerance( useRelTol      )
    , smoothBoundaryEdges ( smoothBoundary )
    , tolerance           ( tol            )
    , bAngle              ( angle          )
    , surfReconstructMode ( reconMode      )
    , brepCreationMode    ( bMode          )
  {}
};


//------------------------------------------------------------------------------
/** \brief \ru Параметры вписывания поверхности.
           \en Parameters of surface fitting. \~
  \ingroup Polygonal_Objects
*/
// ---
class MATH_CLASS MbSurfaceFitToGridParameters {
private:
  MbeSpaceType           _surfaceType;         ///< \ru Тип поверхности. \en A surface type.
  double                 _tolerance;           ///< \ru Точность распознавания. \en A fitting tolerance.
  c3d::IndicesVector     _indicies;            ///< \ru Индексы полигонов сетки. \en Indicies of polygons.
  MbeRejectOutliersType  _typeReject;          ///< \ru Способ отбраковки выбросов. \en Outliers rejection mode.
  double                 _valueReject;         ///< \ru Пороговое значения для отбраковки выбросов. \en Outliers rejection mode treshold value.
  MbSurfaceFitConstraint _fitConstraint;       ///< \ru Ограничение. \en Constraint.
  size_t                 _pointsFittingMax;    ///< \ru Максимальное количество точек для вписывания. \en Maximum count of fitting points.
  bool                   _withRefinement;      ///< \ru Уточнять ли поверхность по всем точкам. \en Refine the surface by all the points or not.

  ///< \ru Предельные значения параметров аналитических поверхностей. \en Thresholds for analytical surfaces parameters.
  double _angleConeMin;             ///< \ru Минимально возможный половинный угол конуса (градусы). \en Mininmum allowed cone half-angle ( degrees ).
  double _angleConeMax;             ///< \ru Максимально возможный половинный угол конуса (градусы). \en Maximum allowed cone half-angle( degrees ).
  double _radiusAnalyticShapeMax;   ///< \ru Максимально возможный радиальный размер аналитических поверхностей. \en Maximum allowed analytical shapes radial size.

  ///< \ru Параметры для вписывания нурбс поверхности. \en NURBs surface fitting parameters.
  size_t _order;        ///< \ru Порядок нурбс поверхности. \en NURBs surface order.
  size_t _countCpMax;   ///< \ru Максимально разрешенное количество контрольных точек. \en Maximum allowed control points count.
  double _smoothCoef;   ///< \ru Коэффициент сглаживания [1e-9 - 1e-3]. \en Smoothing coefficient [1e-9 - 1e-3].

private:
  /// \ru Конструктор по умолчанию. \en Default constructor.
  MbSurfaceFitToGridParameters() 
    : _surfaceType           ( st_Undefined                )
    , _tolerance             ( c3d::DELTA_MIN              )
    , _indicies              (                             )
    , _typeReject            ( rot_NoReject                )
    , _valueReject           ( 0.                          )
    , _pointsFittingMax      ( 10000                       )
    , _withRefinement        ( false                       )
    , _order                 ( c3d::NURBS_DEGREE           )
    , _countCpMax            ( c3d::NURBS_POINTS_MAX_COUNT )
    , _smoothCoef            ( METRIC_ACCURACY             )
    , _angleConeMin          ( 1.                          )
    , _angleConeMax          ( 89.                         )
    , _radiusAnalyticShapeMax( 1500.                       )
  {}

public:
  /// \ru Конструктор по параметрам. \en Constructor by parameters.
  explicit MbSurfaceFitToGridParameters(       MbeSpaceType         surfaceType,
                                               double               tolerance,
                                         const c3d::IndicesVector & indicies )
    : _surfaceType           ( surfaceType                 )
    , _tolerance             ( tolerance                   )
    , _indicies              ( indicies                    )
    , _typeReject            ( rot_NoReject                )
    , _valueReject           ( 0.                          )
    , _pointsFittingMax      ( 10000                       )
    , _withRefinement        ( false                       )
    , _order                 ( c3d::NURBS_DEGREE           )
    , _countCpMax            ( c3d::NURBS_POINTS_MAX_COUNT )
    , _smoothCoef            ( METRIC_ACCURACY             )
    , _angleConeMin          ( 1.                          )
    , _angleConeMax          ( 89.                         )
    , _radiusAnalyticShapeMax( 1500.                       )
  {}

  /// \ru Конструктор по параметрам. \en Constructor by parameters.
  explicit MbSurfaceFitToGridParameters(       MbeSpaceType          surfaceType,
                                               double                tolerance,
                                         const c3d::IndicesVector &  indicies,
                                               MbeRejectOutliersType rejectType,
                                               double                rejectValue )
    : _surfaceType           ( surfaceType                 )
    , _tolerance             ( tolerance                   )
    , _indicies              ( indicies                    )
    , _typeReject            ( rejectType                  )
    , _valueReject           ( rejectValue                 )
    , _pointsFittingMax      ( 10000                       )
    , _withRefinement        ( false                       )
    , _order                 ( c3d::NURBS_DEGREE           )
    , _countCpMax            ( c3d::NURBS_POINTS_MAX_COUNT )
    , _smoothCoef            ( METRIC_ACCURACY             )
    , _angleConeMin          ( 1.                          )
    , _angleConeMax          ( 89.                         )
    , _radiusAnalyticShapeMax( 1500.                       )
  {}

  /// \ru Конструктор по параметрам для вписывания аналитических поверхностей. \en Constructor by parameters for analytic surfaces fitting.
  explicit MbSurfaceFitToGridParameters(       MbeSpaceType               surfaceType,
                                               double                     tolerance,
                                         const c3d::IndicesVector &       indicies,
                                               MbeRejectOutliersType      rejectType,
                                               double                     rejectValue,
                                               double                     angleConeMin, 
                                               double                     angleConeMax,
                                               double                     radiusAnalyticShapeMax )
    : _surfaceType           ( surfaceType                 )
    , _tolerance             ( tolerance                   )
    , _indicies              ( indicies                    )
    , _typeReject            ( rejectType                  )
    , _valueReject           ( rejectValue                 )
    , _pointsFittingMax      ( 10000                       )
    , _withRefinement        ( false                       )
    , _order                 ( c3d::NURBS_DEGREE           )
    , _countCpMax            ( c3d::NURBS_POINTS_MAX_COUNT )
    , _smoothCoef            ( METRIC_ACCURACY             )
    , _angleConeMin          ( angleConeMin                )
    , _angleConeMax          ( angleConeMax                )
    , _radiusAnalyticShapeMax( radiusAnalyticShapeMax      )
  {}

  /// \ru Конструктор по параметрам для вписывания нурбс поверхности. \en Constructor by parameters for NURBs surface fitting.
  explicit MbSurfaceFitToGridParameters(       MbeSpaceType         surfaceType,
                                               double               tolerance,
                                         const c3d::IndicesVector & indicies,
                                               size_t               order, 
                                               size_t               countCpMax,
                                               double               smoothCoef )
    : _surfaceType           ( surfaceType                 )
    , _tolerance             ( tolerance                   )
    , _indicies              ( indicies                    )
    , _typeReject            ( rot_NoReject                )
    , _valueReject           ( 0.                          )
    , _pointsFittingMax      ( 10000                       )
    , _withRefinement        ( false                       )
    , _order                 ( order                       )
    , _countCpMax            ( countCpMax                  )
    , _smoothCoef            ( smoothCoef                  )
    , _angleConeMin          ( 1.                          )
    , _angleConeMax          ( 89.                         )
    , _radiusAnalyticShapeMax( 1500.                       )
  {}

  /// \ru Выдать тип поверхности. \en Get surface type.
  MbeSpaceType GetSurfaceType() const { return _surfaceType; }
  /// \ru Выдать точность распознавания. \en Get fitting tolerance.
  double GetTolerance() const { return _tolerance; }
  /// \ru Выдать индексы полигонов. \en Get indicies of polygons.
  const c3d::IndicesVector & GetIndicies() const { return _indicies; }
  /// \ru Выдать метод отбраковки выбросов. \en Get outliers rejection mode.
  MbeRejectOutliersType GetOutliersRejectionMode() const { return _typeReject; }
  /// \ru Выдать пороговое значения для отбраковки выбросов. \en Get outliers rejection mode treshold value. 
  double GetOutliersRejectionValue() const { return _valueReject; }
  /// \ru Выдать порядок нурбс поверхности. \en Get NURBs order. 
  size_t GetNurbsOrder() const { return _order; }
  /// \ru Выдать максимально разрешенное количество контрольных точек. \en Get maximum allowed control points count.
  size_t GetCountCpMax() const { return _countCpMax; }
  /// \ru Выдать коэффициент сглаживания. \en Get smoothing coefficient.
  double GetSmoothCoef() const { return _smoothCoef; }
  /// \ru Выдать минимально возможный половинный угол конуса. \en Get mininmum allowed cone half-angle.
  double GetAngleConeMin() const { return _angleConeMin; }
  /// \ru Выдать максимально возможный половинный угол конуса. \en Get maximum allowed cone half-angle.
  double GetAngleConeMax() const { return _angleConeMax; }
  /// \ru Выдать максимально возможный радиальный размер аналитических поверхностей. \en Get maximum allowed analytical shapes radial size.
  double GetRadiusAnalyticShapeMax() const { return _radiusAnalyticShapeMax; }
  /// \ru Выдать ограничение. \en Get the constraint.
  const MbSurfaceFitConstraint & GetFitConstraint() const { return _fitConstraint; }
  /// \ru Выдать максимальное количество точек для вписывания. \en Get the maximum count of fitting points.
  size_t GetPointsFittingMax() const { return _pointsFittingMax; }
  /// \ru Выдать флаг уточнения поверхности по всем точкам. \en Get the flag of surface refinement by all the points.
  bool GetWithRefinement() const { return _withRefinement; }
  /// \ru Установить предельные значения параметров аналитических поверхностей. \en Set thresholds for analytical surfaces parameters.
  void SetAnalyticBounds( double angleConeMin, double angleConeMax, double radiusAnalyticShapeMax )
  {
    _angleConeMin = angleConeMin;
    _angleConeMax = angleConeMax;
    _radiusAnalyticShapeMax = radiusAnalyticShapeMax;
  }
  /// \ru Установить параметры для вписывания нурбс поверхности. \en Set NURBs surface fitting parameters.
  void SetNurbsFitParams( size_t order, size_t countCpMax, double smoothCoef )
  {
    _order = order;
    _countCpMax = countCpMax;
    _smoothCoef = smoothCoef;
  }
  /** \brief \ru Ограничить ось примитива.
             \en Add an axis constraint. \~
    \details \ru Ограничить ось цилиндра, конуса или тора, а также нормаль плоскости.
                 По умолчанию ось примитива или нормаль плоскости будет коллинеарна направлению direction.
                 Дополнительно можно задать желаемый угол angle между осью примитива или нормалью плоскости и заданным направлением из промежутка [0; П/2].
                 Для построения плоскости с нормалью, которая перпендикулярна заданному направлению, необходимо задать угол П/2.
                 Функция сбрасывает выставленные ранее ограничения на ось.
             \en Add an axis constraint to a cylinder, cone, torus or plane. 
                 The axis of a primitive or plane normal will be collinear to a given direction by default.
                 Besides there may be given a desired angle between the axis of a primitive or plane normal and a given direction from [0; П/2].
                 Fitting a plane with a normal, which is perpendicular to a given direction, implies an angle П/2.
                 The function resets all previous axis constraints. \~
    \param[in] direction - \ru Эталонное направление.
                           \en Reference direction. \~
    \param[in] angle     - \ru Угол между осью примитива и заданным направлением.
                           \en Angle between the axis of a primitive and a given direction. \~
    \return \ru Возвращает true, если задан корректный угол, и false - иначе.
            \en Returns true, if an angle is correct, or false otherwise. \~
    \ingroup Polygonal_Objects
  */
  bool AddAxisConstraint( const MbVector3D & direction, double angle = 0. )
  {
    return _fitConstraint.AddAxisConstraint( direction, angle );
  }
  /** \brief \ru Зафиксировать ось примитива.
             \en Add a coaxial constraint. \~
    \details \ru Зафиксировать ось цилиндра, конуса, тора или сферы.
                 Вписывается примитив с заданной осью.
                 Если вписывается сфера, ее центр лежит на заданной оси.
                 Функция сбрасывает выставленные ранее ограничения на ось.
             \en Add a coaxial constraint to a cylinder, cone, torus or sphere.
                 A primitive will be fit with a given axis.
                 If a sphere is fit, its center lies on a given axis.
                 The function resets all previous axis constraints. \~
    \param[in] axis - \ru Ось.
                      \en Axis. \~
    \ingroup Polygonal_Objects
  */
  void AddCoaxialConstraint( const MbAxis3D & axis )
  {
    return _fitConstraint.AddCoaxialConstraint( axis );
  }
  /** \brief \ru Зафиксировать радиус цилиндра.
             \en Fix cylinder radius. \~
    \details \ru Зафиксировать радиус цилиндра.
                 Радиус должен быть положительным.
             \en Fix cylinder radius.
                 The value has to be positive. \~
    \param[in] radius - \ru Радиус цилиндра.
                        \en Cylinder radius. \~
    \return \ru Возвращает true, если задан корректный радиус, и false - иначе.
            \en Returns true, if a radius is correct, or false otherwise. \~
    \ingroup Polygonal_Objects
  */
  bool AddCylinderRadiusConstraint( double radius )
  {
    return _fitConstraint.AddCylinderRadiusConstraint( radius );
  }
  /** \brief \ru Зафиксировать радиус сферы.
             \en Fix sphere radius. \~
    \details \ru Зафиксировать радиус сферы.
                 Радиус должен быть положительным.
             \en Fix sphere radius.
                 The value has to be positive. \~
    \param[in] radius - \ru Радиус сферы.
                        \en Sphere radius. \~
    \return \ru Возвращает true, если задан корректный радиус, и false - иначе.
            \en Returns true, if a radius is correct, or false otherwise. \~
    \ingroup Polygonal_Objects
  */
  bool AddSphereRadiusConstraint( double radius )
  {
    return _fitConstraint.AddSphereRadiusConstraint( radius );
  }
  /** \brief \ru Зафиксировать угол конуса.
             \en Fix cone angle. \~
    \details \ru Зафиксировать угол конуса.
                 Угол должен быть из промежутка (0; П/2).
             \en Fix cone angle.
                 The angle has to be from (0; П/2). \~
    \param[in] angle - \ru Угол конуса.
                       \en Cone angle. \~
    \return \ru Возвращает true, если задан корректный угол, и false - иначе.
            \en Returns true, if an angle is correct, or false otherwise. \~
    \ingroup Polygonal_Objects
  */
  bool AddConeAngleConstraint( double angle )
  {
    return _fitConstraint.AddConeAngleConstraint( angle );
  }
  /** \brief \ru Зафиксировать радиусы тора.
             \en Fix torus radii. \~
    \details \ru Зафиксировать радиусы тора.
                 Можно зафиксировать большой и малый радиусы тора (только один их них или сразу оба).
                 Значения должны быть положительными (=0 - значение не зафиксировано).
             \en Fix torus radii.
                 There may be fixed the major radius (_size1) or the minor radius (_size2) of a torus (one or both of them).
                 The values have to be positive (=0 - value is not fixed). \~
    \param[in] majorRadius - \ru Большой радиус тора.
                             \en Major torus radius. \~
    \param[in] minorRadius - \ru Малый радиус тора.
                             \en Minor torus radius. \~
    \return \ru Возвращает true, если заданы корректные радиусы, и false - иначе.
            \en Returns true, if radii are correct, or false otherwise. \~
    \ingroup Polygonal_Objects
  */
  bool AddTorusRadiiConstraint( double majorRadius, double minorRadius )
  {
    return _fitConstraint.AddTorusRadiiConstraint( majorRadius, minorRadius );
  }
  /** \brief \ru Установить ограничение типа XYW.
             \en Set the XYW-constraint. \~
    \details \ru Установить ограничение типа XYW.
                 Ограничение типа XYW допускает только параллельный перенос вдоль осей OX и OY и поворот вокруг оси OZ заданной системы координат. 
                 Для плоскости, цилиндра, конуса или тора должен быть зафиксирован угол theta между осью объекта и осью OZ заданной СК.
                 Угол theta должен принадлежать отрезку [0; П/2].
                 Для сферы должна быть зафиксирована координата z ее центра в заданной СК.
                 Для тора должна быть зафиксирована координата z центра его направляющей окружности в заданной СК.
                 При необходимости можно зафиксировать размерные параметры объекта.
                 Функция сбрасывает выставленные ранее ограничения (например, добавленные с помощью методов "Add*Constraint").
             \en Set the XYW-constraint. 
                 Translation along the OX и OY axes and rotation about the OZ axis of a local coordinate system are only allowed.
                 For a plane, a cylinder, a cone or a torus there has to be fixed the angle theta between an object's axis and the OZ axis of a given coordinate system.
                 The angle theta has to belong to [0; П/2].
                 For a sphere there has to be fixed the Z coordinate of its center.
                 For a torus there has to be fixed the Z coordinate of its directrix circle.
                 There may be fixed some dimensional parameters of an object if necessary.
                 The function resets all previous constraints (for example, having been set by "Add*Constraint"). \~
    \param[in] typeSurface - \ru Тип поверхности.
                             \en Surface type. \~
    \param[in] typeDim     - \ru Тип размерного ограничения.
                             \en Dimensional constraint type. \~
    \param[in] fixedValues - \ru Фиксированные значения параметров поверхности.
                             \en Structure with fixed values of surface parameters. \~
    \param[in] place       - \ru Локальная система координат.
                             \en Local coordinate system. \~
    \return \ru Возвращает код результата операции.
            \en Returns operation result code. \~
    \ingroup Polygonal_Objects
  */
  MbResultType SetFitConstraintXYW(       MbeSpaceType                 typeSurface,
                                          MbeDimensionalConstraintType typeDim,
                                    const MbConstraintFixedValues &    fixedValues,
                                    const MbPlacement3D &              place )
  {
    return _fitConstraint.InitializeXYW( typeSurface, typeDim, fixedValues, place );
  }
  /** \brief \ru Установить ограничение типа Z.
             \en Set the Z-constraint. \~
    \details \ru Установить ограничение типа Z.
                 Ограничение типа Z допускает только сдвиг вдоль оси OZ заданной системы координат.
                 Для плоскости, цилиндра, конуса или тора должны быть зафиксированы:
                 - зенитный угол theta: угол между осью объекта и осью OZ заданной СК, должен принадлежать отрезку [0; П/2],
                 - азимутальный угол phi: угол между проекцией оси объекта на плоскость OXY и осью OX заданной СК, 
                 должен принадлежать промежутку [0; 2П).
                 Для цилиндра, конуса или тора должны быть зафиксированы координаты x и y некоторой точки на оси объекта.
                 Для сферы должны быть зафиксированы координаты x и y ее центра в заданной СК.
                 При необходимости можно зафиксировать размерные параметры объекта.
                 Функция сбрасывает выставленные ранее ограничения (например, добавленные с помощью методов "Add*Constraint").
             \en Set the Z-constraint.
                 Translation along the OZ axis of a local coordinate system is only allowed.
                 For a plane, a cylinder, a cone or a torus there have to be fixed:
                 - the zenith angle theta: the angle between an object's axis and the OZ axis of a given CS, has to belong to [0; П/2],
                 - the azimuthal angle phi: the angle between the projection of an object's axis onto the OXY plane 
                 and the OX axis of a given CS, has to belong to [0; 2П).
                 For a cylinder, a cone or a torus there have to be fixed the X and Y coordinates of a point of an object's axis.
                 For a sphere there have to be fixed the X and Y coordinates of its center.
                 There may be fixed some dimensional parameters of an object if necessary.
                 The function resets all previous constraints (for example, having been set by "Add*Constraint"). \~
    \param[in] typeSurface - \ru Тип поверхности.
                             \en Surface type. \~
    \param[in] typeDim     - \ru Тип размерного ограничения.
                             \en Dimensional constraint type. \~
    \param[in] fixedValues - \ru Фиксированные значения параметров поверхности.
                             \en Structure with fixed values of surface parameters. \~
    \param[in] place       - \ru Локальная система координат.
                             \en Local coordinate system. \~
    \return \ru Возвращает код результата операции.
            \en Returns operation result code. \~
    \ingroup Polygonal_Objects
  */
  MbResultType SetFitConstraintZ(       MbeSpaceType                 typeSurface,
                                        MbeDimensionalConstraintType typeDim,
                                  const MbConstraintFixedValues &    fixedValues,
                                  const MbPlacement3D &              place )
  {
    return _fitConstraint.InitializeZ( typeSurface, typeDim, fixedValues, place );
  }
  /** \brief \ru Установить ограничение типа XYZ.
             \en Set the XYZ-constraint. \~
    \details \ru Установить ограничение типа XYZ.
                 Ограничение типа XYZ допускает только параллельный перенос (запрещены повороты вокруг координатных осей заданной системы координат).
                 Для плоскости, цилиндра, конуса или тора должны быть зафиксированы:
                 - зенитный угол theta: угол между осью объекта и осью OZ заданной СК, должен принадлежать отрезку [0; П/2],
                 - азимутальный угол phi: угол между проекцией оси объекта на плоскость OXY и осью OX заданной СК, 
                 должен принадлежать промежутку [0; 2П).
                 При необходимости можно зафиксировать размерные параметры объекта.
                 Функция сбрасывает выставленные ранее ограничения (например, добавленные с помощью методов "Add*Constraint").
             \en Set the XYZ-constraint.
                 Translation is only allowed (any rotation is forbidden).
                 For a plane, a cylinder, a cone or a torus there have to be fixed:
                 - the zenith angle theta: the angle between an object's axis and the OZ axis of a given CS, has to belong to [0; П/2],
                 - the azimuthal angle phi: the angle between the projection of an object's axis onto the OXY plane 
                 and the OX axis of a given CS, has to belong to [0; 2П).
                 There may be fixed some dimensional parameters of an object if necessary.
                 The function resets all previous constraints (for example, having been set by "Add*Constraint"). \~
    \param[in] typeSurface - \ru Тип поверхности.
                             \en Surface type. \~
    \param[in] typeDim     - \ru Тип размерного ограничения.
                             \en Dimensional constraint type. \~
    \param[in] fixedValues - \ru Фиксированные значения параметров поверхности.
                             \en Structure with fixed values of surface parameters. \~
    \param[in] place       - \ru Локальная система координат.
                             \en Local coordinate system. \~
    \return \ru Возвращает код результата операции.
            \en Returns operation result code. \~
    \ingroup Polygonal_Objects
  */
  MbResultType SetFitConstraintXYZ(       MbeSpaceType                 typeSurface,
                                          MbeDimensionalConstraintType typeDim,
                                    const MbConstraintFixedValues &    fixedValues,
                                    const MbPlacement3D &              place )
  {
    return _fitConstraint.InitializeXYZ( typeSurface, typeDim, fixedValues, place );
  }
  /** \brief \ru Установить ограничение типа ZW.
             \en Set the ZW-constraint. \~
    \details \ru Установить ограничение типа ZW.
                 Ограничение типа ZW допускает только сдвиг вдоль оси OZ и поворот вокруг оси OZ заданной системы координат.
                 Для плоскости, цилиндра, конуса или тора должны быть зафиксированы:
                 - зенитный угол theta: угол между осью объекта и осью OZ заданной СК, должен принадлежать отрезку [0; П/2],
                 - начальный азимутальный угол phi: угол между проекцией оси объекта в начальной позиции на плоскость OXY и осью OX заданной СК,
                 должен принадлежать промежутку [0; 2П),
                 - расстояние dist от оси OZ заданной СК до оси объекта.
                 Для cферы должно быть зафиксировано расстояние dist от ее центра до оси OZ заданной СК.
                 При необходимости можно зафиксировать размерные параметры объекта.
                 Функция сбрасывает выставленные ранее ограничения (например, добавленные с помощью методов "Add*Constraint").
             \en Set the ZW-constraint.
                 Translation along the OZ axis and rotation about the OZ axis of a local coordinate system are only allowed.
                 For a plane, a cylinder, a cone or a torus there have to be fixed:
                 - the zenith angle theta: the angle between an object's axis and the OZ axis of a given CS, has to belong to [0; П/2],
                 - the initial azimuthal angle phi: the angle between the projection of an object's axis in the initial position onto the OXY plane
                 and the OX axis of a given CS, has to belong to [0; 2П),
                 - the distance between an object's axis the OZ axis of a given CS.
                 For a sphere there has to be fixed the distance between its center and the OZ axis of a given CS.
                 There may be fixed some dimensional parameters of an object if necessary.
                 The function resets all previous constraints (for example, having been set by "Add*Constraint"). \~
    \param[in] typeSurface - \ru Тип поверхности.
                             \en Surface type. \~
    \param[in] typeDim     - \ru Тип размерного ограничения.
                             \en Dimensional constraint type. \~
    \param[in] fixedValues - \ru Фиксированные значения параметров поверхности.
                             \en Structure with fixed values of surface parameters. \~
    \param[in] place       - \ru Локальная система координат.
                             \en Local coordinate system. \~
    \return \ru Возвращает код результата операции.
            \en Returns operation result code. \~
    \ingroup Polygonal_Objects
  */
  MbResultType SetFitConstraintZW(       MbeSpaceType                 typeSurface,
                                         MbeDimensionalConstraintType typeDim,
                                   const MbConstraintFixedValues &    fixedValues,
                                   const MbPlacement3D &              place )
  {
    return _fitConstraint.InitializeZW( typeSurface, typeDim, fixedValues, place );
  }
  /// \ru Установить максимальное количество точек для вписывания. \en Set the maximum count of fitting points.
  void SetPointsFittingMax( size_t value ) { _pointsFittingMax = value; }
  /// \ru Установить флаг уточнения поверхности по всем точкам. \en Set the flag of surface refinement by all the points.
  void SetWithRefinement( bool value ) { _withRefinement = value; }

  OBVIOUS_PRIVATE_COPY( MbSurfaceFitToGridParameters )
};


//------------------------------------------------------------------------------
/** \brief \ru Результат вписывания поверхности.
           \en Parameters of surface fitting. \~
  \ingroup Polygonal_Objects
*/
// ---
class MATH_CLASS MbSurfaceFitToGridResults {
private:
  c3d::SurfaceSPtr _surface;   ///< \ru Поверхность. \en A surface. 
  double           _devMax;    ///< \ru Максимальное получившееся отклонение. \en A maximal deviation. 
  double           _devMean;   ///< \ru Среднее получившееся отклонение. \en A mean deviation. 
  double           _rmsd;      ///< \ru Среднее квадратическое отклонение. \en A root-mean-square deviation. 
public:
  /// \ru Конструктор по умолчанию. \en Default constructor.
  MbSurfaceFitToGridResults()
    : _surface( nullptr )
    , _devMax ( 0.0     )
    , _devMean( 0.0     )
    , _rmsd   ( 0.0     )
  {}
  /// \ru Конструктор по параметрам. \en Constructor by parameters.
  MbSurfaceFitToGridResults( MbSurface * surface, double tolerance )
    : _surface( surface   )
    , _devMax ( tolerance )
    , _devMean( 0.0       )
    , _rmsd   ( 0.0       )
  {}
  /// \ru Конструктор по параметрам. \en Constructor by parameters.
  MbSurfaceFitToGridResults( MbSurface * surface, double devMax, double devMean, double rmsd )
    : _surface( surface )
    , _devMax ( devMax  )
    , _devMean( devMean )
    , _rmsd   ( rmsd    )
  {}
  /// \ru Инициализировать данные. \en Initialize data.
  void Init( MbSurface * surface, double tolerance ) {
    _surface = surface;
    _devMax = tolerance;
    _devMean = 0.;
    _rmsd = 0.;
  }
  /// \ru Инициализировать данные. \en Initialize data.
  void Init( MbSurface * surface, double devMax, double devMean, double rmsd ) {
    _surface = surface;
    _devMax = devMax;
    _devMean = devMean;
    _rmsd = rmsd;
  }
  /// \ru Выдать поверхность. \en Get surface.
  c3d::SurfaceSPtr GetSurface() const { return _surface; }
  /// \ru Выдать максимальное отклонение. \en Get maximal deviation.
  double GetTolerance() const { return _devMax; }
  /// \ru Выдать среднее отклонение. \en Get mean deviation.
  double GetMeanDeviation() const { return _devMean; }
  /// \ru Выдать cреднее квадратическое отклонение. \en Get root-mean-square deviation.
  double GetRmsd() const { return _rmsd; }

  OBVIOUS_PRIVATE_COPY( MbSurfaceFitToGridResults )
};



//------------------------------------------------------------------------------
/** \brief \ru Класс для создания оболочки в граничном представлении по полигональной сетке.
           \en Class for creating a BRep shell by polygonal mesh. \~
  \details \ru Предоставить интерфейс для управления преобразованием сетки в
               оболочку в граничном представлении. \n
           \en Provide an interface for managing of "Mesh to BRep" conversion. \n \~
  \ingroup Polygonal_Objects
*/
// ---
class MATH_CLASS MbMeshProcessor : public MbRefItem
{
protected:
  /// \ru Конструктор. \en Constructor. 
  MbMeshProcessor();

public:
  /** \brief \ru Создать экземпляр процессора по коллекции.
             \en Create mesh processor by collection. \~
    \details \ru Создать экземпляр процессора по коллекции. Пользователь должен сам удалить объект.
             \en Create mesh processor by collection. User must delete created object. \~
    \param[in] collection - \ru Входная коллекция, содержащая треугольную сетку. \n
                            \en Input collection containing triangle mesh. \~
    \return \ru Возвращает указатель на созданный объект.
            \en Returns pointer to created object. \~
    \ingroup Polygonal_Objects
  */
  static MbMeshProcessor * Create( const MbCollection & collection );

  /// \ru Деструктор. \en Destructor. 
  virtual ~MbMeshProcessor();

  /** \brief \ru Установить относительную точность.
             \en Set relative tolerance. \~
    \details \ru Установить относительную точность по габаритам текущей сетки.
             \en Set relative tolerance by current mesh box. \~
    \param[in] tolerance - \ru Относительная точность. \n
                           \en Relative tolerance to set. \~
    \ingroup Polygonal_Objects
  */
  virtual void SetRelativeTolerance( double tolerance ) = 0;

  /** \brief \ru Установить точность.
             \en Set tolerance. \~
    \details \ru Установить точность распознавания поверхностей и расширения сегментов сетки.
                 Метод должен быть вызван перед вызовом SegmentMesh.
                 Точность по умолчанию равна 0.1.
             \en Set tolerance of surface reconstruction and segments extension.
                 Method should be called before call to SegmentMesh.
                 Default tolerance is 0.1. \n \~
    \param[in] tolerance - \ru Точность. \n
                           \en Tolerance to set. \~
    \ingroup Polygonal_Objects
  */
  virtual void SetTolerance( double tolerance ) = 0;

  /** \brief \ru Получить точность.
             \en Get tolerance. \~
    \details \ru Получить текущую точность, используемую при распознавании поверхностей и расширения сегментов сетки.
             \en Get current tolerance used in surface reconstruction and segments extension. \~
    \return \ru Возвращает абсолютную точность.
            \en Returns absolute tolerance. \~
    \ingroup Polygonal_Objects
  */
  virtual double GetTolerance() const = 0;

  //------------------------------------------------------------------------------
  /** \brief \ru Установить режим распознавания поверхностей.
             \en Set the surfaces reconstruction mode. \~
    \details \ru Задать типы поверхностей, генерируемых на сегментах. Поверхности неподдерживаемых типов строиться не будут. \n
             \en Set types of surfaces which will be generated on segments. The surfaces of unsupoprted type will not be built. \n \~
    \param[in]  mode  - \ru Режим распознавания поверхностей.
                        \en Surface reconstruction mode.
    \ingroup Polygonal_Objects
  */
  virtual void SetReconstructionMode( MbeSurfReconstructMode mode ) = 0;


  //------------------------------------------------------------------------------
  /** \brief \ru Установить режим построения модели BRep.
             \en Set the BRep creation mode. \~
    \details \ru Задать степень связности граней в результирующей модели BRep. \n
             \en Set connectivity type of faces of resultant BRep model. \n \~
    \param[in]  mode  - \ru Режим построения модели BRep.
                        \en BRep creation mode.
    \ingroup Polygonal_Objects
  */
  virtual void SetBrepCreationMode( MbeCreateBRepMode mode ) = 0;

  //------------------------------------------------------------------------------
  /** \brief \ru Установить флаг сглаживания входной сетки.
             \en Set flag to use smoothing of input mesh. \~
    \details \ru Установить флаг сглаживания входной сетки. Если флаг установлен в true,
                 то перед запуском основного алгоритма сегментации будет выполнено сглаживание входной сетки.
                 Рекомендуется использовать сглаживание на неточных сетках, например, полученных методом сканирования. \n
             \en Set flag to use smoothing of input mesh. If the flag set to true, then run smoothing of input mesh
                 before main segmentation algorithm start.
                 It is recommended to use mesh smoothing on inexact meshes, e.g. meshes obtained by scanning. \n \~
    \param[in]  useSmoothing  - \ru Флаг использования сглаживания входной сетки. По-умолчанию false.
                                \en The flag to use smoothing of input mesh. Default false.
    \ingroup Polygonal_Objects
  */
  // ---
  virtual void SetUseMeshSmoothing( bool useSmoothing ) = 0;

  /** \brief \ru Получить исправленную (упрощенную) копию входной полигональной сетки.
             \en Get fixed (simplified) copy of the input mesh. \~
    \details \ru Получить исправленную копию входной сетки, на которой выполняются операции MbMeshProcessor:
                 подсчет кривизн, сегментация, построение оболочки. Все индексы в выходных данных соответствуют
                 индексам вершин и треугольников упрощенной сетки, возвращаемой данным методом. \n
             \en Get fixed copy of the input mesh. All further operations of MbMehsProcessor are
                 performed for simplified mesh: curvature calculation, segmentation, shell creation.
                 All indices in the output of these operations corresponds to indices of vertices and
                 triangles of the simplified mesh returned from this function. \n \~
    \return \ru Возвращает исправленную версию входной полигональной сетки.
            \en Returns a fixed version of the input mesh. \~
    \ingroup Polygonal_Objects
  */
  virtual const MbCollection & GetSimplifiedMesh() = 0;

  /** \brief \ru Получить сегментированную копию входной полигональной сетки.
             \en Get segmented copy of the input mesh. \~
    \details \ru Получить сегменитрованную копию входной сетки, на которой выполняются операции MbMeshProcessor:
                 подсчет кривизн, сегментация, построение оболочки.
                 Сегментация доступна внутри коллекции. \n
             \en Get segmented copy of the input mesh. All further operations of MbMehsProcessor are
                 performed for simplified mesh: curvature calculation, segmentation, shell creation.
                 Segmentation is stored inside collection. \n \~
    \return \ru Возвращает сегментированную версию входной полигональной сетки.
              \en Returns a segmented version of the input mesh. \~
    \ingroup Polygonal_Objects
  */
  virtual const MbCollection & GetSegmentedMesh() = 0;

  /** \brief \ru Рассчитать главные кривизны и главные направления изменения кривизн в точках сетки.
             \en Calculate the principal curvatures and principal curvature directions at mesh points. \~
    \details \ru Рассчитать главные кривизны и главные направления изменения кривизн в точках сетки. \n
             \en Calculate the principal curvatures and principal curvature directions at mesh points. \n \~
    \return \ru Возвращает главные кривизны и главные направления в точках сетки.
            \en Returns principal curvatures and principal curvature directions at mesh points. \~
    \ingroup Polygonal_Objects
  */
  virtual const std::vector<MbCurvature> & CalculateCurvatures() = 0;

  /** \brief \ru Сегментровать полигональную сетку.
             \en Segment a polygonal mesh. \~
    \details \ru Выполнить сегментацию полигональной сетки. \n
             \en Perform segmentation of a polygonal mesh. \n \~
    \return  \ru Возвращает код результата операции.
             \en Returns operation result code. \~
    \param[in] createSurfaces - \ru Создавать ли поверхности на сегментах.
                                \en Create surfaces on segments or not. \~
    \ingroup Polygonal_Objects
  */
  virtual MbResultType SegmentMesh( bool createSurfaces = true ) = 0;

  /** \brief \ru Создать оболочку.
             \en Create shell. \~
    \details \ru Создать оболочку в граничном представлении, соответствующее модели, заданной полигональной сеткой.
                 Используется текущая сегментация.
                 Если сегментация не была вычислена, то вычисляется автоматическая сегментация (с параметрами по умолчанию). \n
             \en Create BRep shell that represents input mesh model.
                 Current segmentation is used.
                 If segmentation is not computed yet, then automatic segmentation is performed (with default parameters). \n \~
    \param[out] pShell - \ru Указатель на созданную оболочку.
                          \en The pointer to created shell. \~
    \param[in] smoothBoundaryEdges - \ru Флаг сглаживания краевых ребер.
                                     \en Smoothing flag of boundary edges. \~
    \param[in] bondThresholdAngle - \ru Предельное значение угла между соседними внешними ребрами сетки в радианах.
                                    \en The treshold value of angle between two adjanced external edges of mesh (in radians). \~
    \return  \ru Возвращает код результата операции.
             \en Returns operation result code. \~
    \ingroup Polygonal_Objects
  */
  virtual MbResultType CreateBRepShell( MbFaceShell *& pShell, bool smoothBoundaryEdges, double bondThresholdAngle ) = 0;

  /** \brief \ru Вписать поверхность.
             \en Fit surface to segment . \~
    \details \ru Распознать поверхность по сегменту сетки с заданным индексом.
                 Распознанная поверхность может быть получена с помощью метода GetSegmentSurface. \n
             \en Recognize surface for mesh segment with a given index.
                 Recognized surface is available through GetSegmentSurface method. \n \~
    \param[in] idxSegment - \ru Индекс сегмента полигональной сетки.
                            \en Index of a mesh segment. \~
    \ingroup Polygonal_Objects
  */
  virtual void FitSurfaceToSegment( size_t idxSegment ) = 0;

  /** \brief \ru Вписать поверхность заданного типа.
             \en Fit surface of a given type to a segment. \~
    \details \ru Построить поверхность заданного типа, аппроксимирующиую сегмент сетки с заданным индексом.
                 Распознанная поверхность может быть получена с помощью метода GetSegmentSurface. \n
             \en Find surface of a given type approximating mesh segment with a given index.
                 Recognized surface is available through GetSegmentSurface method. \n \~
    \param[in] idxSegment  - \ru Индекс сегмента полигональной сетки.
                             \en Index of a mesh segment. \~
    \param[in] surfaceType - \ru Тип вписываемой поверхности.
                             \en Type of fitted surface. \~
    \ingroup Polygonal_Objects
  */
  virtual void FitSurfaceToSegment( size_t idxSegment, MbeSpaceType surfaceType ) = 0;

  /** \brief \ru Получить поверхность для сегмента.
             \en Get surface of segment. \~
    \details \ru Получить поверхность, вписанную в сегмент.
                 Чтобы поверхность была определена предварительно должны быть вызваны методы
                 SegmentMesh или FitSurfaceToSegment.
                 Распознанная поверхность с помощью метода GetSegmentSurface. \n
             \en Get surface that approximates segment.
                 To fit surface use corresponding methods SegmentMesh or FitSurfaceToSegment. \n \~
    \param[in] idxSegment - \ru Индекс сегмента полигональной сетки.
                            \en Index of a mesh segment. \~
    \return  \ru Возвращает указатель на поверхность для сегмента, если поверхность определена, иначе - nullptr.
             \en Returns pointer to segment surface if it exists, else - nullptr. \~
    \ingroup Polygonal_Objects
  */
  virtual const MbSurface * GetSegmentSurface( size_t idxSegment ) const = 0;
  /** \brief \ru Установить поверхность для сегмента.
             \en Set surface of segment. \~
    \details \ru Установить поверхность, вписанную в сегмент.
                 Чтобы поверхность была определена предварительно должны быть вызваны методы
                 SegmentMesh или FitSurfaceToSegment.
                 Распознанная поверхность с помощью метода GetSegmentSurface. \n
             \en Set surface that approximates segment.
                 To fit surface use corresponding methods SegmentMesh or FitSurfaceToSegment. \n \~
    \param[in] idxSegment - \ru Индекс сегмента полигональной сетки.
                            \en Index of a mesh segment. \~
    \return  \ru Возвращает указатель на поверхность для сегмента, если поверхность определена, иначе - nullptr.
             \en Returns pointer to segment surface if it exists, else - nullptr. \~
    \ingroup Polygonal_Objects
  */
  virtual MbSurface * SetSegmentSurface( size_t idxSegment ) = 0;
  /** \brief \ru Очистить сегментацию полигональной сетки.
             \en Reset segmentation of the polygonal mesh. \~
    \details \ru Очистить сегментацию полигональной сетки, хранящуюся внутри MbMeshProcessor. \n
             \en Reset segmentation of the polygonal mesh stored inside MbMeshProcessor. \n \~
    \ingroup Polygonal_Objects
  */
  virtual void ResetSegmentation() = 0;

  /** \brief \ru Найти ближайший путь между двумя вершинами коллекции.
             \en Find shortest path between two vertices. \~
    \details \ru Найти ближайший путь, проходящий по вершинам и ребрам коллекции, соединяющий две заданные вершины. \n
             \en Find shortest path between two vertices. The path should pass through collection vertices and edges. \n \~
    \param[in]  v1   - \ru Индекс первой вершины.
                       \en The index of first vertex. \~
    \param[in]  v2   - \ru Индекс второй вершины.
                       \en The index of second vertex. \~
    \param[out] path - \ru Путь из первой вершины во вторую.
                           Массив содержит последовательные индексы всех вершин пути.
                       \en The path from the first vertex to the second one.
                           The array contains successive indices of path vertices. \~
    \return  \ru Возвращает код результата операции.
             \en Returns operation result code. \~
    \ingroup Polygonal_Objects
  */
  virtual bool FindShortestVertexPath( uint v1, uint v2, std::vector<uint> & path ) = 0;

private: // UNDER DEVELOPMENT
  /** \} */
  /** \ru \name Функции для работы с разбиением сетки на сегменты и распознаванием поверхностей для сегментов.
      \en \name Functions for editting of mesh segmentation and reconstruction of surfaces for the segments.
      \{ */

  /** \brief \ru Объединить два сегмента в текущей сегментации.
             \en Unite two segments in current segmentation. \~
    \details \ru Объединение сегментов в текущей сегментации.
                 Результат объединения доступен через коллекцию, возвращаемую методом GetSegmentedMesh. \n
             \en Union of segments in current mesh segmentation.
                 Result segmentation is available through collection returned by GetSegmentedMesh. \n \~
    \param[in] firstSegmentIdx - \ru Индекс первого сегмента для объединения. \n
                                 \en Index of the first segment for union. \~
    \param[in] secondSegmentIdx - \ru Индекс второго сегмента для объединения. \n
                                  \en Index of the second segment for union. \~
    \ingroup Polygonal_Objects
  */
  virtual void UniteSegments( size_t firstSegmentIdx, size_t secondSegmentIdx ) = 0;

  /** \brief \ru Сегментровать полигональную сетку по разделителям сегментов.
             \en Segment a polygonal mesh by segment separators. \~
    \details \ru Выполнить сегментацию полигональной сетки по заданным разделителям сегментов. \n
             \en Perform segmentation of a polygonal mesh by segment separators. \n \~
    \param[in]  separators  - \ru Массив разделителей.
                                  Каждый разделитель содержит путь по вершинам сетки, ребра которого разделяют сегменты.
                              \en The array of segment separators.
                                  Each separator contains a path by mesh vertices. Edges of that path split mesh to segments. \~
    \return  \ru Возвращает код результата операции.
             \en Returns operation result code. \~
    \ingroup Polygonal_Objects
  */
  virtual MbResultType SegmentMeshBySeparators( const std::vector<c3d::UintVector> & separators ) = 0;

  OBVIOUS_PRIVATE_COPY( MbMeshProcessor )
};


//------------------------------------------------------------------------------
/** \brief \ru Создать оболочку по полигональной сетке c автоматическим распознаванием поверхностей.
           \en Create shell from mesh with automatic surface reconstruction. \~
  \details \ru Создать оболочку в граничном представлении, соответствующее модели, заданной полигональной сеткой.
               Алгоритм в автоматическом режиме распознает и реконструирует грани, соответствующие элементарным
               поверхностям (плоскость, цилиндр, сфера, конус, тор). \n
           \en Create BRep shell that represents input mesh model.
               Algorithm automatically detect and reconstruct faces based on elementary surfaces (plane, cylinder, sphere, cone, torus). \n \~
  \param[in]  mesh      - \ru Входная сетка.
                          \en The input mesh. \~
  \param[out] shell     - \ru Указатель на созданную оболочку.
                          \en The pointer to created shell. \~
  \param[in]  params    - \ru Параметры построения оболочки тела.
                          \en Parameters of BRep shell construction. \~
  \return  \ru Возвращает код результата операции.
           \en Returns operation result code. \~
  \ingroup Polygonal_Objects
*/
// ---
MATH_FUNC( MbResultType ) ConvertMeshToShell( MbMesh & mesh, MbFaceShell *& shell, const MbMeshProcessorValues & params = MbMeshProcessorValues() );


//------------------------------------------------------------------------------
/** \brief \ru Создать оболочку по коллекции, содержащей полигональную сетку c автоматическим распознаванием поверхностей.
           \en Create shell from collection with automatic surface reconstruction. \~
  \details \ru Создать оболочку в граничном представлении, соответствующую модели, заданной полигональной сеткой.
               Алгоритм в автоматическом режиме распознает и реконструирует грани, соответствующие элементарным
               поверхностям (плоскость, цилиндр, сфера, конус, тор). \n
           \en Create BRep shell that represents input mesh model from collection.
               Algorithm automatically detect and reconstruct faces based on elementary surfaces (plane, cylinder, sphere, cone, torus). \n \~
  \param[in]  collection  - \ru Коллекция, содержащая входную сетку.
                            \en The input collection. \~
  \param[out] shell       - \ru Указатель на созданную оболочку.
                            \en The pointer to created shell. \~
  \param[in]  params      - \ru Параметры построения оболочки тела.
                            \en Parameters of BRep shell construction. \~
  \return  \ru Возвращает код результата операции.
           \en Returns operation result code. \~
  \ingroup Polygonal_Objects
*/
// ---
MATH_FUNC( MbResultType ) ConvertCollectionToShell( MbCollection & collection, MbFaceShell *& shell, const MbMeshProcessorValues & params = MbMeshProcessorValues() );


//------------------------------------------------------------------------------
/** \brief \ru Вписать поверхность в множество полигонов сетки.
           \en Fit the surface into polygon set. \~
  \details \ru Вписать поверхность заданного типа в множество полигонов триангуляции. \n
               В случае если множество полигонов не задано, используются
               все полигоны триангуляции.
           \en Fit a surface of a given type into the polygon set. \n
               If the set of polygons is not specified, all triangulation polygons are used. \~
  \param[in]  grid  - \ru Исходная триангуляция.
                      \en The initial triangulation. \~
  \param[in]  params - \ru Параметры вписывания поверхности.
                       \en The fitting parameters. \~
  \param[out] results - \ru Результаты вписывания поверхности.
                        \en Results of surface fitting. \~
  \return  \ru Возвращает код результата операции.
           \en Returns operation result code. \~
  \warning \ru В разработке.
           \en Under development. \~
  \ingroup Polygonal_Objects
*/
// ---
MATH_FUNC( MbResultType ) FitSurfaceToGrid( const MbGrid & grid, const MbSurfaceFitToGridParameters & params, MbSurfaceFitToGridResults & results );
#endif // __ACTION_B_SHAPER_H
