//////////////////////////////////////////////////////////////////////////////// /** \file \brief \ru Радиальный размер к поверхности. Расстояние между поверхностями. \en Radial dimension of surface. Distance between surfaces. \~ \details \ru Функции построения окружности или дуги для радиального размера к поверхности. Функция вычисления экстремальных расстояний между поверхностями. \en Functions of construction of a circle or an arc for radial dimension of surface. A function of calculation of extreme distances between surfaces. \~ */ //////////////////////////////////////////////////////////////////////////////// #ifndef __ALG_DIMENSION_H #define __ALG_DIMENSION_H #include #include #include #include #include class MATH_CLASS MbCartPoint3D; class MATH_CLASS MbVector3D; class MATH_CLASS MbPlacement3D; class MATH_CLASS MbAxis3D; class MATH_CLASS MbPlaneCurve; class MATH_CLASS IProgressIndicator; //////////////////////////////////////////////////////////////////////////////// // // \ru Построение окружности или дуги для радиального размера к поверхности, \en Construction of a circle or an arc for radial dimension of surface // \ru имеющей круговую параметрическую линию u=const или v=const \en which has a circular parametric line u=const or v=const. // \ru Перечень поверхностей, имеющих параметрическую линию u=const или u=const: \en The enumeration of surfaces which have a parametric line u=const or u=const: // MbCylinderSurface, v=const // MbConeSurface, v=const // MbSphereSurface, u=const // MbTorusSurface, u=const // MbLoftedSurface, v=const // MbElevationSurface, v=const // MbExtrusionSurface, v=const // MbRevolutionSurface, u=const // MbEvolutionSurface, u=const // MbExactionSurface, u=const // //////////////////////////////////////////////////////////////////////////////// //------------------------------------------------------------------------------ /** \brief \ru Построить окружность или дугу для радиального размера к поверхности. \en Construct a circle or an arc for radial dimension of surface. \~ \details \ru Построение выполняется по заданной параметрической точке поверхности. Поверхность должна иметь круговую параметрическую линию u=const или v=const. Перечень поверхностей, имеющих параметрическую линию u=const или v=const: MbCylinderSurface v=const, \n MbConeSurface v=const, \n MbSphereSurface u=const, \n MbTorusSurface u=const, \n MbLoftedSurface v=const, \n MbElevationSurface v=const, \n MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n MbEvolutionSurface u=const, \n MbExactionSurface u=const. \en Construction is performed by the given parametric point on surface. A surface should have a circular parametric line u=const or v=const. The enumeration of surfaces which have a parametric line u=const or v=const. MbCylinderSurface v=const, \n MbConeSurface v=const, \n MbSphereSurface u=const, \n MbTorusSurface u=const, \n MbLoftedSurface v=const, \n MbElevationSurface v=const, \n MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n MbEvolutionSurface u=const, \n MbExactionSurface u=const. \~ \param[in] surface - \ru Исходная поверхность. \en The initial surface. \~ \param[in] surface_uv - \ru Координаты исходной точки на поверхности. \en Coordinates of the initial point on surface. \~ \param[out] plane_curve - \ru Требуемая окружность или дуга. \en The required circle or an arc. \~ \ingroup Algorithms_3D */ // --- MATH_FUNC (void) RadiusDimension3D( const MbSurface & surface, const MbCartPoint & surface_uv, MbPlaneCurve *& plane_curve ); //------------------------------------------------------------------------------ /** \brief \ru Построить окружность или дугу для радиального размера к поверхности. \en Construct a circle or an arc for radial dimension of surface. \~ \details \ru Построение выполняется по заданной по заданной пространственной точке. Поверхность должна иметь круговую параметрическую линию u=const или v=const. Перечень поверхностей, имеющих параметрическую линию u=const или u=const: MbCylinderSurface v=const, \n MbConeSurface v=const, \n MbSphereSurface u=const, \n MbTorusSurface u=const, \n MbLoftedSurface v=const, \n MbElevationSurface v=const, \n MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n MbEvolutionSurface u=const, \n MbExactionSurface u=const. \en Construction is performed by the given spatial point. A surface should have a circular parametric line u=const or v=const. The enumeration of surfaces which have a parametric line u=const or v=const. MbCylinderSurface v=const, \n MbConeSurface v=const, \n MbSphereSurface u=const, \n MbTorusSurface u=const, \n MbLoftedSurface v=const, \n MbElevationSurface v=const, \n MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n MbEvolutionSurface u=const, \n MbExactionSurface u=const. \~ \param[in] surface - \ru Исходная поверхность. \en The initial surface. \~ \param[in] point - \ru Пространственные координаты исходной точки. \en Space coordinates of the initial point. \~ \param[out] plane_curve - \ru Требуемая окружность или дуга. \en The required circle or an arc. \~ \ingroup Algorithms_3D */ // --- MATH_FUNC (void) RadiusDimension3D( const MbSurface & surface, const MbCartPoint3D & point, MbPlaneCurve *& plane_curve ); //------------------------------------------------------------------------------ /** \brief \ru Построить окружность или дугу для радиального размера к поверхности. \en Construct a circle or an arc for radial dimension of surface. \~ \details \ru Построение выполняется по заданному плейсменту. Поверхность должна иметь круговую параметрическую линию u=const или v=const. Перечень поверхностей, имеющих параметрическую линию u=const или u=const: MbCylinderSurface v=const, \n MbConeSurface v=const, \n MbSphereSurface u=const, \n MbTorusSurface u=const, \n MbLoftedSurface v=const, \n MbElevationSurface v=const, \n MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n MbEvolutionSurface u=const, \n MbExactionSurface u=const. \en Construction is performed by the given placement. A surface should have a circular parametric line u=const or v=const. The enumeration of surfaces with a parametric line u=const or v=const. MbCylinderSurface v=const, \n MbConeSurface v=const, \n MbSphereSurface u=const, \n MbTorusSurface u=const, \n MbLoftedSurface v=const, \n MbElevationSurface v=const, \n MbExtrusionSurface v=const, \n MbRevolutionSurface u=const, \n MbEvolutionSurface u=const, \n MbExactionSurface u=const. \~ \param[in] surface - \ru Исходная поверхность. \en The initial surface. \~ \param[in] place - \ru Исходный плейсмент. \en The initial placement. \~ \param[out] plane_curve - \ru Требуемая окружность или дуга. \en The required circle or an arc. \~ \ingroup Algorithms_3D */ // --- MATH_FUNC (void) RadiusDimension3D( const MbSurface & surface, const MbPlacement3D & place, MbPlaneCurve *& plane_curve ); //------------------------------------------------------------------------------ /** \brief \ru Можно ли построить окружность или дугу для радиального размера к поверхности. \en Whether a circle or an arc can be constructed for radial dimension of surface. \~ \details \ru Можно построить, если тип базовой поверхности: st_CylinderSurface или st_ConeSurface, или st_SphereSurface, или st_TorusSurface. \en It can be constructed if the type of a base surface is st_CylinderSurface or st_ConeSurface, or st_SphereSurface, or st_TorusSurface. \~ \param[in] surface - \ru Исходная поверхность. \en The initial surface. \~ \return \ru true, если можно построить. \en true if it can be constructed. \~ \ingroup Algorithms_3D */ // --- MATH_FUNC (bool) IsPossibleRadiusDimension3D( const MbSurface & surface ); //------------------------------------------------------------------------------ /** \brief \ru Результат замера расстояния и угла между поверхностями. \en The result of measurement of dimension and angle between surfaces. \~ \details \ru Результат замера расстояния и угла между поверхностями. \en The result of measurement of dimension and angle between surfaces. \~ \ingroup Algorithms_3D */ // --- enum MbeSurfAxesMeasureRes { // \ru ошибочные результат \en mistaken result samr_SurfSurf_Failed = -3, ///< \ru Ошибка при работе с поверхностями. \en An error is occurred while working with surfaces. samr_AxisSurf_Failed = -2, ///< \ru Ошибка при работе с осью и поверхностью. \en An error is occurred while working with axis and surface. samr_AxisAxis_Failed = -1, ///< \ru Ошибка при работе с осями. \en An error is occurred while working with axes. // \ru пустой результат \en an empty result. samr_Undefined = 0, ///< \ru Не получилось или не измерялось. \en Failed or didn't measured. // \ru две оси \en two axes samr_AxisAxis_Coaxial, ///< \ru Оси совпадают. \en Axes are coincident. samr_AxisAxis_Parallel, ///< \ru Оси параллельны. \en Axes are parallel. samr_AxisAxis_Intersecting, ///< \ru Оси пересекаются. \en Axes are crossed. samr_AxisAxis_Distant, ///< \ru Оси на расстоянии. \en Axes are located at a distance. // \ru одна ось (какая из осей есть, см. по возвращаемому флагу функции замера) \en one axis (see the returned flag of measurement function to detect which one exactly) samr_AxisSurf_Colinear, ///< \ru Ось лежит на поверхности. \en The axis lies on the surface. samr_AxisSurf_Parallel, ///< \ru Ось параллельна поверхности. \en The axis is parallel to the surface. samr_AxisSurf_Intersecting, ///< \ru Ось пересекает поверхность. \en The axis crosses the surface. samr_AxisSurf_Distant, ///< \ru Ось на расстоянии от поверхности. \en The axis is located at a distance from the surface. // \ru две плоские поверхности \en two planar surfaces samr_SurfSurf_Colinear, ///< \ru Одна поверхность лежит на другой. \en One surface lies on another one. samr_SurfSurf_Parallel, ///< \ru Поверхности параллельны. \en Surfaces are parallel. samr_SurfSurf_Intersecting, ///< \ru Поверхности пересекаются. \en Surfaces are intersecting inside domain. // \ru samr_SurfSurf_Distant, // находятся на расстоянии \en samr_SurfSurf_Distant, // located at a distance }; //------------------------------------------------------------------------------ /** \brief \ru Расстояние между осями поверхностей. \en Distance between axes of surfaces. \~ \details \ru Рассчитывается расстояние между осями поверхностей, имеющих оси вращения, или расстояние между поверхностью, имеющей ось, и плоской поверхностью. \en Calculate distance between axes of revolution surfaces or distance between revolution surface and planar surface. \~ \param[in] surface1, sameSense1 - \ru Первая поверхность и ее направление. \en The first surface and its direction. \~ \param[in] surface2, sameSense2 - \ru Вторая поверхность и ее направление. \en The second surface and its direction. \~ \param[out] axis1, exist1 - \ru Ось первой поверхности и флаг ее наличия. \en The axis of the first surface and the flag of its existence. \~ \param[out] axis2, exist2 - \ru Ось второй поверхности и флаг ее наличия. \en The axis of the second surface and the flag of its existence. \~ \param[out] p1 - \ru Точка на первой оси или поверхности. \en The point on the first axis or surface. \~ \param[out] p2 - \ru Точка на второй оси или поверхности. \en The point on the second axis or surface. \~ \param[out] angle - \ru Угол между осями или осью поверхностью. \en The angle between axes or between an axis and a surface. \~ \param[out] distance - \ru Минимальное расстояние между осями. \en Minimal distance between axes. \~ \param[in] angle - \ru Угловая погрешность. \en The angle accuracy. \~ \return \ru Вариант полученного замера или вариант ошибки. \en The variant of the obtained measurement or the variant of error. \~ \ingroup Algorithms_3D */ // --- MATH_FUNC (MbeSurfAxesMeasureRes) SurfAxesDistAngle( const MbSurface & surface1, bool sameSense1, const MbSurface & surface2, bool sameSense2, MbAxis3D & axis1, bool & exist1, MbAxis3D & axis2, bool & exist2, MbCartPoint3D & p1, MbCartPoint3D & p2, double & angle, double & distance, double angleEps = ANGLE_EPSILON ); //------------------------------------------------------------------------------ /** \brief \ru Расстояние между точками на объектах (кривая-кривая, кривая-поверхность или поверхность-поверхность). \en Distance between points on objects (curve-curve, curve-surface, surface-surface). \~ \details \ru Класс содержит данные о расстоянии между точками и координатами этих точек на объектах. \en The class contains data about the distance between points and their coordinates on objects surfaces. \~ \ingroup Algorithms_3D */ // --- template class MbItemItemDist { template friend class MbMinMaxItemItemDistances; private: double d; ///< \ru Расстояние. \en Distance. Param1 par1; ///< \ru Параметр на первом объекте. \en Parameter on the first object. Param2 par2; ///< \ru Параметр на втором объекте. \en Parameter on the second object. uint8 sign; ///< \ru Знак расстояния. \en Sign of direction. public: /// \ru Параметрическая точка (1D или 2D). \en Parametric point (1D or 2D). struct ParamPoint { double x; double y; bool s; ParamPoint( double t ) : x( t ), y( t ), s( false ) {} ParamPoint( const MbCartPoint & p ) : x( p.x ), y( p.y ), s( true ) {} }; public: /// \ru Конструктор. \en Constructor. MbItemItemDist() : d( UNDEFINED_DBL ), par1(), par2(), sign( 1 ) {} /// \ru Конструктор по данным. \en The constructor by data. MbItemItemDist( double _d, const Param1 & _par1, const Param2 & _par2, bool plus ) { Init( _d, _par1, _par2, plus ); } /// \ru Конструктор копирования. \en Copy constructor. MbItemItemDist( const MbItemItemDist & other ) { Init( other ); } /// \ru Деструктор. \en The destructor. virtual ~MbItemItemDist() {} public: /// \ru Функция копирования. \en Copy function. void Init( const MbItemItemDist & obj ) { d = obj.d; par1 = obj.par1; par2 = obj.par2; sign = obj.sign; } /// \ru Получить расстояние. \en Get distance. double GetDistance() const { return d; } /// \ru Получить точку на первой поверхности. \en Get the point on the first surface. const Param1 & GetParamOne() const { return par1; } /// \ru Получить точку на второй поверхности. \en Get the point on the second surface. const Param2 & GetParamTwo() const { return par2; } /// \ru Расстояние положительное? \en Is the distance positive? bool IsPositive() const { return (sign > 0); } /// \ru Расстояние отрицательное? \en Is the distance negative? bool IsNegative() const { return (sign < 1); } /// \ru Оператор присваивания. \en Assignment operator. const MbItemItemDist & operator = ( const MbItemItemDist & other ) { Init( other ); return (*this); } private: // \ru Инициализатор. \en Initializer. void Init( double _d, const Param1 & _par1, const Param2 & _par2, bool plus ) { d = _d; par1 = _par1; par2 = _par2; sign = plus ? 1 : 0; } }; //------------------------------------------------------------------------------ // MbItemItemDist typedefs // --- typedef MbItemItemDist MbCurvCurvDist; typedef MbItemItemDist MbCurvSurfDist; typedef MbItemItemDist MbSurfCurvDist; typedef MbItemItemDist MbSurfSurfDist; DEPRECATE_DECLARE_REPLACE( MbSurfSurfDist ) typedef MbSurfSurfDist MbSurfDist; // old //------------------------------------------------------------------------------ // сортировать по возрастанию расстояния // --- template bool ItemItemDistCompFunc( const ItemItemDist & sd1, const ItemItemDist & sd2 ) { bool isFirstLessSecond = false; const double mEps = LENGTH_EPSILON; const double pEps = PARAM_EPSILON; double d1 = sd1.GetDistance(); double d2 = sd2.GetDistance(); if ( d1 < d2 - mEps ) isFirstLessSecond = true; else if ( ::fabs( d1 - d2 ) <= mEps ) { const typename ItemItemDist::ParamPoint parOne1( sd1.GetParamOne() ); const typename ItemItemDist::ParamPoint parOne2( sd2.GetParamOne() ); if ( parOne1.x < parOne2.x - pEps ) isFirstLessSecond = true; else if ( parOne1.s && parOne2.s && ::fabs( parOne1.x - parOne2.x ) <= pEps ) { if ( parOne1.y < parOne2.y - pEps ) isFirstLessSecond = true; else if ( ::fabs( parOne1.y - parOne2.y ) <= pEps ) { if ( d1 < d2 ) isFirstLessSecond = true; } } } return isFirstLessSecond; } //------------------------------------------------------------------------------ /** \brief \ru Расстояния с точками между поверхностями. \en Distances between surfaces with points. \~ \details \ru Расстояния с точками между поверхностями. \en Distances between surfaces with points. \~ \ingroup Algorithms_3D */ // --- template class MbMinMaxItemItemDistances { private : std::vector< MbItemItemDist > allDistances; ///< \ru Расстояние и параметры на поверхностях. \en Distance and parameters on surfaces. mutable double midDistance; ///< \ru Среднее расстояние. \en Average distance. mutable double minDistance; ///< \ru Минимальное расстояние. \en Minimal distance. mutable double maxDistance; ///< \ru Максимальное расстояние. \en Maximal distance. mutable bool sorted; ///< \ru Признак сортированности. \en Attribute of being sorted. public: /// \ru Конструктор. \en Constructor. MbMinMaxItemItemDistances( size_t nReserve = 0 ) : allDistances( ) , midDistance ( UNDEFINED_DBL ) , minDistance ( UNDEFINED_DBL ) , maxDistance ( UNDEFINED_DBL ) , sorted ( false ) { allDistances.reserve( std_min( nReserve, (size_t)c3d::COUNT_MAX ) ); } /// \ru Деструктор. \en Destructor. virtual ~MbMinMaxItemItemDistances() { RemoveAll( true ); } public: bool IsEmpty() const { return allDistances.empty(); } ///< \ru Есть ли замеры? \en Are there any measurements? size_t GetCount() const { return allDistances.size(); } ///< \ru Количество замеров. \en The number of measurements. ptrdiff_t GetMaxIndex() const { return ((ptrdiff_t)allDistances.size() - 1); } ///< \ru Индекс последнего замера. \en Index of the last measurement /// \ru Зарезервировать память под nReserve элементов. \en Reserve memory for 'nReserve' elements. void Reserve( size_t nReserve ) { allDistances.reserve( allDistances.size() + nReserve ); } /// \ru Удалить все элементы. \en Delete all elements. void RemoveAll( bool freeMemory ) { allDistances.clear(); if ( freeMemory ) { allDistances.shrink_to_fit(); } midDistance = minDistance = maxDistance = UNDEFINED_DBL; } /// \ru Освободить лишнюю память. \en Free the unnecessary memory. void AdjustMemory() { allDistances.shrink_to_fit(); } public: /// \ru Получить расстояние по индексу. \en Get the distance by the index. bool GetDistance( size_t k, double & d ) const { if ( k < allDistances.size() ) { d = allDistances[k].GetDistance(); return true; } return false; } /// \ru Получить расстояние со знаком, по индексу. \en Get the signed distance by the index. bool GetSignedDistance( size_t k, double & d ) const { if ( k < allDistances.size() ) { d = allDistances[k].GetDistance(); if ( allDistances[k].IsNegative() ) d = -d; return true; } return false; } /// \ru Считаем ли вы расстояние отрицательным. \en Whether the distance is negative. bool IsNegativeDistance( size_t k ) const { return ((k < allDistances.size()) ? allDistances[k].IsNegative() : false); } /// \ru Получить минимальное расстояние. \en Get minimal distance. bool GetMinDistance( double & d ) const { bool res = false; size_t count = allDistances.size(); if ( count > 0 ) { if ( minDistance != UNDEFINED_DBL ) { d = minDistance; res = true; } else if ( count > 1 ) { minDistance = MB_MAXDOUBLE; for ( size_t k = 0; k < count; ++k ) { double curDistance = allDistances[k].GetDistance(); if ( curDistance < minDistance ) { minDistance = curDistance; res = true; } } if ( res ) d = minDistance; else minDistance = UNDEFINED_DBL; } else { minDistance = allDistances.front().GetDistance(); d = minDistance; res = true; } } return res; } /// \ru Получить максимальное расстояние. \en Get maximal distance. bool GetMaxDistance( double & d ) const { bool res = false; size_t count = allDistances.size(); if ( count > 0 ) { if ( maxDistance != UNDEFINED_DBL ) { d = maxDistance; res = true; } else if ( count > 1 ) { maxDistance = -MB_MAXDOUBLE; for ( size_t k = 0; k < count; ++k ) { double curDistance = allDistances[k].GetDistance(); if ( curDistance > maxDistance ) { maxDistance = curDistance; res = true; } } if ( res ) d = maxDistance; else maxDistance = UNDEFINED_DBL; } else { maxDistance = allDistances.front().GetDistance(); d = maxDistance; res = true; } } return res; } /// \ru Получить среднее расстояние. \en Get average distance. bool GetMidDistance( double & d ) const { bool res = false; size_t count = allDistances.size(); if ( count > 0 ) { if ( count > 1 ) { if ( midDistance != UNDEFINED_DBL ) { d = midDistance; res = true; } else { midDistance = 0.0; for ( size_t k = 0; k < count; ++k ) midDistance += allDistances[k].GetDistance(); midDistance /= ((double)count); d = midDistance; res = true; } } else { midDistance = allDistances.front().GetDistance(); d = midDistance; res = true; } } return res; } /// \ru Получить расстояние и точки на поверхностях. \en Get distance and points on surface. bool GetItemDistance( size_t k, double & d, Param1 & par1, Param2 & par2 ) const { if ( k < allDistances.size() ) { d = allDistances[k].GetDistance(); par1 = allDistances[k].GetParamOne(); par2 = allDistances[k].GetParamTwo(); return true; } return false; } DEPRECATE_DECLARE_REPLACE( GetItemDistance ) bool GetSurfDistance( size_t k, double & d, Param1 & par1, Param2 & par2 ) const { return GetItemDistance( k, d, par1, par2 ); } /// \ru Получить расстояние и точки на поверхностях. \en Get distance and points on surface. bool GetItemDistance( size_t k, double & d, bool & plus, Param1 & par1, Param2 & par2 ) const { if ( k < allDistances.size() ) { d = allDistances[k].GetDistance(); par1 = allDistances[k].GetParamOne(); par2 = allDistances[k].GetParamTwo(); plus = allDistances[k].IsPositive(); return true; } return false; } DEPRECATE_DECLARE_REPLACE( GetItemDistance ) bool GetSurfDistance( size_t k, double & d, bool & plus, Param1 & par1, Param2 & par2 ) const { return GetItemDistance( k, d, plus, par1, par2 ); } /// \ru Добавить расстояние и точки на поверхностях. \en Add distance and points on surface. bool AddItemDistance( double d, bool plus, const Param1 & par1, const Param2 & par2, bool addEqual, double eps = LENGTH_EPSILON ) { if ( ::fabs( d ) < LENGTH_EPSILON ) d = 0.0; C3D_ASSERT( d >= 0 ); if ( d > 0.0 ) { size_t count = allDistances.size(); bool add = true; if ( !addEqual ) { for ( size_t k = 0; k < count; ++k ) { if ( ::fabs( d - allDistances[k].GetDistance() ) < eps ) { add = false; break; } } } if ( add ) { if ( count > 0 ) { if ( maxDistance != UNDEFINED_DBL && d > maxDistance ) maxDistance = d; else if ( minDistance != UNDEFINED_DBL && d < minDistance ) minDistance = d; } else minDistance = maxDistance = d; MbItemItemDist surfDistance( d, par1, par2, plus ); allDistances.push_back( surfDistance ); midDistance = UNDEFINED_DBL; return true; } } return false; } /// \ru Добавить расстояние и точки на поверхностях. \en Add distance and points on surface. DEPRECATE_DECLARE_REPLACE( AddItemDistance ) bool AddSurfDistance( double d, bool plus, const Param1 & par1, const Param2 & par2, bool addEqual, double eps = LENGTH_EPSILON ) { return AddItemDistance( d, plus, par1, par2, addEqual, eps ); } /// \ru Сортировать по возрастанию расстояния. \en Sort by distance in the ascending order. void Sort() { if ( allDistances.size() > 1 ) { std::sort( allDistances.begin(), allDistances.end(), ItemItemDistCompFunc< MbItemItemDist > ); minDistance = allDistances.front().GetDistance(); maxDistance = allDistances.back().GetDistance(); sorted = true; } } /// \ru Убрать объекты с одинаковыми расстояниями. \en Remove objects with similar distances. void RemoveEqualDistances( double eps = LENGTH_EPSILON ) { if ( allDistances.size() > 1 ) { if ( !sorted ) Sort(); bool wasRemoved = false; for ( ptrdiff_t k = ((ptrdiff_t)allDistances.size() - 1); k > 0; k-- ) { ptrdiff_t m = k - 1; double dThis = allDistances[k].GetDistance(); double dPrev = allDistances[m].GetDistance(); if ( ::fabs( dThis - dPrev ) < eps ) { allDistances.erase( allDistances.begin() + m ); wasRemoved = true; } } if ( wasRemoved ) { midDistance = UNDEFINED_DBL; minDistance = allDistances.front().GetDistance(); maxDistance = allDistances.back().GetDistance(); } } } /// \ru Оператор присваивания. \en Assignment operator. void operator = ( const MbMinMaxItemItemDistances & other ) { allDistances = other.allDistances; // \ru расстояние и параметры на поверхностях midDistance = other.midDistance; // \ru среднее расстояние minDistance = other.minDistance; // \ru минимальное расстояние maxDistance = other.maxDistance; // \ru максимальное расстояние sorted = other.sorted; // \ru признак сортированности } private: MbMinMaxItemItemDistances( const MbMinMaxItemItemDistances & ); }; //------------------------------------------------------------------------------ // MbMinMaxSurfSurfDists typedefs // --- typedef MbMinMaxItemItemDistances MbMinMaxCurvCurvDists; typedef MbMinMaxItemItemDistances MbMinMaxCurvSurfDists; typedef MbMinMaxItemItemDistances MbMinMaxSurfCurvDists; typedef MbMinMaxItemItemDistances MbMinMaxSurfSurfDists; DEPRECATE_DECLARE_REPLACE( MbMinMaxSurfSurfDists ) typedef MbMinMaxItemItemDistances MbMinMaxSurfDists; // old //------------------------------------------------------------------------------ /** \brief \ru Экстремальные расстояния между поверхностями. \en Extreme distances between surfaces. \~ \details \ru Экстремальные расстояния между поверхностями по сетке на первой поверхности, причем замеры осуществляются в заданном направлении (если есть вектор) или по нормалям к первой поверхности. \en Extreme distances between surfaces by mesh on the first surface, measurements are performed in a given direction (if the vector is set) or by normals of the first surface. \~ \param[in] surface1 - \ru Первая поверхность. \en The first surface. \~ \param[in] u1cnt - \ru Количество точек по u (первая поверхность). \en The number of points by u (the first surface) \~ \param[in] v1cnt - \ru Количество точек по v (первая поверхность). \en The number of points by v (the first surface) \~ \param[in] dir - \ru Вектор заданного направления (если нет, то по нормали). \en The vector of direction (if not set then by the normal). \~ \param[in] orient - \ru Относительное направление поиска. \en Relative search direction. \~ \param[in] useEqualDistances - \ru Оставлять равные расстояния. \en Whether to use the equal distances. \~ \param[in] surface2 - \ru Вторая поверхность. \en The second surface. \~ \param[in,out] nMin - \ru Количество регистрируемых минимумов. \en The number of recorded minimums. \~ \param[in,out] nMax - \ru Количество регистрируемых максимумов. \en The number of recorded maximums. \~ \param[out] allResults - \ru Все результаты. \en All results. \~ \param[out] minResults - \ru Результаты-минимумы. \en Results-minimums. \~ \param[out] maxResults - \ru Результаты-максимумы. \en Results-maximums. \~ \param[in,out] indicator - \ru Интерфейс-индикатор процесса выполнения. \en Interface-indicator of the execution process. \~ \return \ru Возвращает результат замера (получен, не получен или же процесс был прерван). \en Returns the result of measurement (obtained, not obtained, or the process has been aborted). \~ \ingroup Algorithms_3D */ // --- //DEPRECATE_DECLARE_REPLACE( MinMaxSurfaceSurfaceGridDistances ) MATH_FUNC (MbeProcessState) MinMaxDistances( const MbSurface & surface1, ptrdiff_t u1cnt, ptrdiff_t v1cnt, const MbVector3D * dir, const MbeSenseValue & orient, bool useEqualDistances, const MbSurface & surface2, ptrdiff_t & nMin, ptrdiff_t & nMax, MbMinMaxSurfSurfDists & allResults, MbMinMaxSurfSurfDists & minResults, MbMinMaxSurfSurfDists & maxResults, IProgressIndicator * indicator = nullptr ); //------------------------------------------------------------------------------ /** \brief \ru Параметры операции сеточного поиска минимумов и максимумов. \en Parameters of the operation of the grid search for minima and maxima. \~ \details \ru Параметры операции сеточного поиска минимумов и максимумов расстояний между объектами. \en Parameters of the grid search operation for minima and maxima of distances between objects. \~ \ingroup Algorithms_3D */ // --- class MATH_CLASS MbMinMaxGridDistancesParams { public: c3d::ConstSpaceItemSPtr srcItem; ///< \ru Базовый объект (кривая или поверхность). \en Base object (curve or surface). \~ c3d::IndicesPair srcSplitsCount; ///< \ru Количество разбиений (точек). \en Number of partitions (points). \~ c3d::ConstSpaceItemSPtr dstItem; ///< \ru Целевой объект (кривая или поверхность). \en Target object (curve or surface). \~ MbVector3D projDirection; ///< \ru Вектор заданного направления (если нет, то по нормали). \en he vector of direction (if not set then by the normal). \~ MbeSenseValue projOrient; ///< \ru Относительное направление поиска. \en Relative search direction. \~ bool useEqualDistances; ///< \ru Оставлять равные расстояния. \en Whether to use the equal distances. \~ size_t desiredMinimaNumber; ///< \ru Желаемое число выдаваемых минимумов. \en Desired minima number. size_t desiredMaximaNumber; ///< \ru Желаемое число выдаваемых максимумов. \en Desired maxima number. VERSION version; ///< \ru Версия. \en Version. private: mutable IProgressIndicator * progress; ///< \ru Индикатор прогресса выполнения операции. \en A progress indicator of the operation. private: MbMinMaxGridDistancesParams(); // \ru Не реализовано. \en Not implemented. public: /// \ru Конструктор по параметрам. \en Constructor by parameters. MbMinMaxGridDistancesParams( const MbSurface & srcSurface, size_t srcUCnt, size_t srcVCnt, const MbSurface & dstSurface, VERSION ver = Math::DefaultMathVersion() ) : srcItem ( &srcSurface ) , srcSplitsCount ( srcUCnt, srcVCnt ) , dstItem ( &dstSurface ) , projDirection ( ) , projOrient ( orient_BOTH ) , useEqualDistances ( false ) , desiredMinimaNumber( 1 ) , desiredMaximaNumber( 1 ) , version ( ver ) , progress ( nullptr ) {} /// \ru Конструктор по параметрам. \en Constructor by parameters. MbMinMaxGridDistancesParams( const MbSurface & srcSurface, size_t srcUCnt, size_t srcVCnt, const MbVector3D * dir, const MbeSenseValue & orient, bool useEqualDists, const MbSurface & dstSurface, size_t nMin, size_t nMax, VERSION ver = Math::DefaultMathVersion() ) : srcItem ( &srcSurface ) , srcSplitsCount ( srcUCnt, srcVCnt ) , dstItem ( &dstSurface ) , projDirection ( ) , projOrient ( orient ) , useEqualDistances ( useEqualDists ) , desiredMinimaNumber( nMin ) , desiredMaximaNumber( nMax ) , version ( ver ) , progress ( nullptr ) { SetProjectionDirection( dir, orient ); } /// \ru Конструктор по параметрам. \en Constructor by parameters. MbMinMaxGridDistancesParams( const MbCurve3D & srcCurve, size_t srcTCnt, const MbSurface & dstSurface, VERSION ver = Math::DefaultMathVersion() ) : srcItem ( &srcCurve ) , srcSplitsCount ( srcTCnt, 0 ) , dstItem ( &dstSurface ) , projDirection ( ) , projOrient ( orient_BOTH ) , useEqualDistances ( false ) , desiredMinimaNumber( 1 ) , desiredMaximaNumber( 1 ) , version ( ver ) , progress ( nullptr ) {} /// \ru Конструктор по параметрам. \en Constructor by parameters. MbMinMaxGridDistancesParams( const MbCurve3D & srcCurve, size_t srcTCnt, const MbCurve3D & dstCurve, VERSION ver = Math::DefaultMathVersion() ) : srcItem ( &srcCurve ) , srcSplitsCount ( srcTCnt, 0 ) , dstItem ( &dstCurve ) , projDirection ( ) , projOrient ( orient_BOTH ) , useEqualDistances ( false ) , desiredMinimaNumber( 1 ) , desiredMaximaNumber( 1 ) , version ( ver ) , progress ( nullptr ) {} public: /// \ru Получить базовый объект. \en Get base object. const MbSpaceItem & GetBaseItem () const { return *srcItem; } /// \ru Получить целевой объект. \en Get target object. const MbSpaceItem & GetTargetItem() const { return *dstItem; } /// \ru Получить количество разбиений базового объекта. \en Get base object splits count. const c3d::IndicesPair & GetBaseSplitsCount() const { return srcSplitsCount; } /// \ru Получить общий вектора поиска. \en Get general search direction. bool GetProjectionDirection( MbVector3D & dir, MbeSenseValue & orient ) const { if ( projDirection.Length() > LENGTH_EPSILON ) { dir = projDirection; orient = projOrient; return true; } return false; } /// \ru Получить общий вектора поиска. \en Get general search direction. bool GetUseEqualDistances() const { return useEqualDistances; } /// \ru Получить желаемое число выдаваемых минимумов. \en Get desired minima number. size_t GetDesiredMinimaNumber() const { return desiredMinimaNumber; } /// \ru Получить желаемое число выдаваемых максимумов. \en Get desired maxima number. size_t GetDesiredMaximaNumber() const { return desiredMaximaNumber; } /// \ru Получить версию. \en Get version. VERSION GetVersion() const { return version; } public: /// \ru Установить общее направление поиска. \en Set general search direction. bool SetProjectionDirection( const MbVector3D * dirPtr, MbeSenseValue orient ) { if ( dirPtr != nullptr ) { const MbVector3D & dir = *dirPtr; double dirLen = dir.Length(); if ( dirLen > LENGTH_EPSILON && dirLen < c3d::MAX_LENGTH ) { projDirection = dir; projOrient = orient; return true; } } return false; } /// \ru Установить флаг использования одинаковых расстояний. \en Set flag to use equal distances. void SetUseEqualDistances( bool useEqualDists ) { useEqualDistances = useEqualDists; } /// \ru Установить желаемые числа выдаваемых минимумов и максимумов. \en Get desired minima and maxima numbers. void SetDisiredMinMaxNumbers( size_t minNum, size_t maxNum ) { desiredMinimaNumber = minNum; desiredMaximaNumber = maxNum; } public: /// \ru Установить внешний индикатор прогресса выполнения. \en Set external progress indicator. void SetProgressIndicator( IProgressIndicator * prog ) { progress = prog; } /// \ru Установить внешний индикатор прогресса выполнения. \en Set external progress indicator. IProgressIndicator * TakeProgressIndicator() const { return progress; } OBVIOUS_PRIVATE_COPY( MbMinMaxGridDistancesParams ) }; //------------------------------------------------------------------------------ /** \brief \ru Результаты операции сеточного поиска минимумов и максимумов. \en Results of the operation of the grid search for minima and maxima. \~ \details \ru Результаты операции сеточного поиска минимумов и максимумов расстояний между объектами. \en Results of the grid search operation for minima and maxima of distances between objects. \~ \ingroup Algorithms_3D */ // --- template class MbMinMaxGridDistancesResults { public: MbMinMaxItemItemDistances allResults; ///< \ru Все результаты. \en All results. \~ MbMinMaxItemItemDistances minResults; ///< \ru Результаты-минимумы. \en Results-minimums. \~ MbMinMaxItemItemDistances maxResults; ///< \ru Результаты-максимумы. \en Results-maximums. \~ public: /// \ru Получить фактическое число минимумов. \en Get real minima number. size_t GetActualMinimaNumber() const { return minResults.GetCount(); } /// \ru Получить фактическое число максимумов. \en Get desired maxima number. size_t GetActualMaximaNumber() const { return maxResults.GetCount(); } }; //------------------------------------------------------------------------------ /** \brief \ru Экстремальные расстояния между объектами (кривыми или поверхностями). \en Extreme distances between objects (curves or surfaces). \~ \details \ru Экстремальные расстояния между объектами по сетке на первом объекте, причем замеры выполняются в заданном направлении (если есть вектор) или по нормалям к первому объекту. \en Extreme distances between objects along the grid on the first object, and measurements are taken in a given direction (if there is a vector) or along the normal to the first object. \~ \param[in] params - \ru Параметры операции сеточного поиска минимумов и максимумов. \en Parameters of the operation of the grid search for minima and maxima. \~ \param[out] results - \ru Результаты операции сеточного поиска минимумов и максимумов. \en Results of the operation of the grid search for minima and maxima. \~ \return \ru Возвращает результат замера (получен, не получен или же процесс был прерван). \en Returns the result of measurement (obtained, not obtained, or the process has been aborted). \~ \ingroup Algorithms_3D */ // --- MATH_FUNC (MbeProcessState) MinMaxSurfaceSurfaceGridDistances( const MbMinMaxGridDistancesParams & params, MbMinMaxGridDistancesResults & results ); #endif // __ALG_DIMENSION_H