//////////////////////////////////////////////////////////////////////////////// /** \file \brief \ru Функции вычисления шага движения по поверхности и кривой для методов разбивки поверхности GetTesselation(..) и AddTesselation(..). \en Functions for calculation step movement on the surface and the curve for methods of splitting the surface GetTesselation(..) and AddTesselation(..). */ //////////////////////////////////////////////////////////////////////////////// #ifndef __SURF_TESSELLATION_H #define __SURF_TESSELLATION_H #include #include #include #include #include #include #include //------------------------------------------------------------------------------ /** \brief \ru Точка и два нормализованных вектора с их длинами. \en Point and two normalized vectors, and their lengths. \~ \details \ru Точка и два нормализованных вектора с их длинами. \en Point and two normalized vectors, and their lengths. \~ \ingroup Data_Structures */ // --- struct MATH_CLASS MbSpacePntTwoVects { MbCartPoint3D pnt; MbVector3D tauU; MbVector3D tauV; double lenU; double lenV; MbSpacePntTwoVects(); // \ru Конструктор по умолчанию \en Default constructor }; //------------------------------------------------------------------------------ /** \brief \ru Разбивка кривой. \en Curve tessellation. \~ \details \ru Разбивка кривой используется для ускорения группового проецирования точек на кривую. \en Curve tessellation is used to accelerate the projection of a group of points on the curve. \~ \ingroup Data_Structures */ // --- class MATH_CLASS MbCurveTessellation : public MbRefItem { private: MbStepData stepData; ///< \ru Тип шага. \en Step type and Step value. std::vector params; ///< \ru Массив параметров. \en The array of parameters. std::vector pnts; ///< \ru Массив точек. \en The array of points. public: MbCurveTessellation(); // \ru Конструктор по умолчанию \en Default constructor MbCurveTessellation( const MbCurveTessellation & st ); // \ru Конструктор копирования. \en Copy-constructor. ~MbCurveTessellation() {} // \ru Деструктор. \en Destructor. public: bool Init ( MbStepData sData, const std::vector & initParams, const std::vector & initPnts ); // \ru Инициализация параметров. \en Initialization of parameters. bool IsSameParams( const MbStepData & sData, double eps ) const; // \ru Определить, являются ли объекты одинаковыми. \en Determine whether objects are equal. double GetParam ( size_t k ) const; // \ru Выдать параметр по индексу. \en Get parameter by index. MbCartPoint3D GetPoint ( size_t k ) const; // \ru Выдать точку по индексу. \en Get point by index. public: MbCurveTessellation & operator = ( const MbCurveTessellation & st ); }; //------------------------------------------------------------------------------ /** \brief \ru Разбивка поверхности. \en Surface tessellation. \~ \details \ru Разбивка поверхности используется для ускорения группового проецирования точек на поверхность. \en Surface tessellation is used to accelerate the projection of a group of points on the surface. \~ \ingroup Data_Structures */ // --- class MATH_CLASS MbSurfaceTessellation { private: MbStepData stepDataU; ///< \ru Тип шага и величина шага по U. \en Step type and Step value in U-direction. MbStepData stepDataV; ///< \ru Тип шага и величина шага по V. \en Step type and Step value in V-direction. MbRect1D uRange; ///< \ru Диапазон по U. \en Range in u direction. MbRect1D vRange; ///< \ru Диапазон по V. \en Range in v direction. std::vector uParams; ///< \ru Массив параметров по U. \en The array of parameters in u direction. std::vector vParams; ///< \ru Массив параметров по V. \en The array of parameters in u direction. Array2 extPoints; ///< \ru Массив точек и первых производных поверхности. \en An array of points and the first derivatives of the surface. bool ext; ///< \ru Флаг, определяющий, выполнять ли вычисления на продолжении поверхности (если true, то искать). \en A flag defining whether to do calculations on the extension of the surface. public: MbSurfaceTessellation(); // \ru Конструктор по умолчанию \en Default constructor MbSurfaceTessellation( const MbSurfaceTessellation & st ); // \ru Конструктор копирования. \en Copy-constructor. ~MbSurfaceTessellation() {} // \ru Деструктор. \en Destructor. public: bool IsFilled( double ueps, double veps, bool checkExtPoints ) const; // \ru Проверить, является ли разбивка заполненной. \en Check, whether the tessellation is filled. void Clear(); // \ru Очистить данные. \en Clear data. bool Init( MbStepData sdAlongU, MbStepData sdAlongV, bool ext, double u1, double u2, const SArray & uarr, double v1, double v2, const SArray & varr ); // \ru Инициализация данных. \en Data initialization. const MbStepData & GetStepAlongU() const { return stepDataU; } // \ru Дать тип шага вдоль параметра u. \en Give the step type along the parameter u. const MbStepData & GetStepAlongV() const { return stepDataV; } // \ru Дать тип шага вдоль параметра v. \en Give the step type along the parameter v. const MbRect1D & GetURange () const { return uRange; } // \ru Дать диапазон по u. \en Give range by u. size_t GetUCount () const { return uParams.size(); } // \ru Дать количество параметров по u. \en Give the number of parameters by u. double GetUParam ( size_t k ) const { return ((k < uParams.size()) ? uParams[k] : UNDEFINED_DBL ); } // \ru Дать u параметр по индексу. \en Give u parameter by index. void GetUParams( SArray & uArr ) const { uArr = uParams; } // \ru Дать массив u параметров. \en Give an array of u parameters. const MbRect1D & GetVRange () const { return vRange; } // \ru Дать диапазон по v. \en Give range by v. size_t GetVCount () const { return vParams.size(); } // \ru Дать количество параметров по v. \en Give the number of parameters by v. double GetVParam ( size_t k ) const { return ((k < vParams.size()) ? vParams[k] : UNDEFINED_DBL ); } // \ru Дать v параметр по индексу. \en Give v parameter by index. void GetVParams( SArray & vArr ) const { vArr = vParams; } // \ru Дать массив v параметров. \en Give an array of v parameters. bool IsSameParams( const MbStepData & sdAlongU, const MbStepData & sdAlongV, bool ext, double u1, double u2, double ueps, double v1, double v2, double veps ) const; // \ru Проверить, являются ли параметры такимиже. \en Check whether input parameters are the same. bool SetLinePoint( size_t lineIndex, size_t columnIndex, const MbSpacePntTwoVects & lineItem ); // \ru Установить точку. \en Set point. bool GetLinePoint( size_t lineIndex, size_t columnIndex, MbSpacePntTwoVects & lineItem ) const; // \ru Получить точку. \en Get point. void Transform( const MbMatrix3D & matr ); // \ru Преобразовать элемент согласно матрице. \en Transform element according to the matrix. void Move ( const MbVector3D & to ); // \ru Сдвинуть точку на вектор. \en Move point by vector. void Rotate ( const MbAxis3D & a, double angle ); // \ru Повернуть вокруг оси на заданный угол. \en Rotate around an axis by angle. public: MbSurfaceTessellation & operator = ( const MbSurfaceTessellation & st ); // \ru Присвоить значение. \en Assign a value. }; //------------------------------------------------------------------------------ /** \brief \ru Точки и производные поверхности. \en Points and Derivative Surfaces. \~ \details \ru Точки и производные поверхности. \en Points and Derivative Surfaces. \~ \ingroup Data_Structures */ // --- class MATH_CLASS MbSurfaceWorkingData { private: MbCartPoint uv0; ///< \ru Исходный параметр. \en Initial parameter. MbCartPoint uv; ///< \ru Модифицированный параметр. \en Modified parameter. bool ext; ///< \ru Флаг расчета на продолжении. \en Extension flag. MbVector3D ders[sdt_CountDer]; ///< \ru Точка и производные. \en Point and derivatives. MbVector3D norm; ///< \ru Нормаль. \en Normal. public: MbSurfaceWorkingData (); // \ru Конструктор по умолчанию \en Default constructor MbSurfaceWorkingData ( const MbSurfaceWorkingData & ); // \ru Конструктор копирования. \en Copy-constructor. ~MbSurfaceWorkingData() {} // \ru Деструктор. \en Destructor. public: void Init (); // \ru Установить пустые значения. \en Set empty values. void Init ( const MbSurfaceWorkingData & ); // \ru Установить значения. \en Set values. void Move ( const MbVector3D & ); // \ru Сдвинуть значения по вектору. \en Move values by vector. public: void SetPoint ( double u0, double v0, bool ext, double u, double v, const MbCartPoint3D & pnt ); // \ru Установить точку. \en Set point. bool GetPoint ( double u0, double v0, bool ext, double & u, double & v, MbCartPoint3D & pnt ) const; // \ru Получить точку. \en Get point. bool SetDerivative( double u0, double v0, bool ext, double u, double v, size_t k, const MbVector3D & der ); // \ru Установить производную. \en Set derivative. bool GetDerivative( double u0, double v0, bool ext, double & u, double & v, size_t k, MbVector3D & der ) const; // \ru Получить производную. \en Get derivative. void _SetParams0 ( double u0, double v0, bool ext0 ); // \ru Установить исходный параметр. \en Set initial parameter. void _SetParams ( double u, double v ); // \ru Установить модифицированный параметр. \en Set modified parameter. bool _SetDerivative( size_t k, const MbVector3D & der ); // \ru Установить производную. \en Set derivative. void _SetNormal ( const MbVector3D & n );// \ru Установить нормаль. \en Set normal. bool Explore ( double u0, double v0, bool ext, double & u, double & v, MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const; // \ru Получить данные. \en Get data. private: MbSurfaceWorkingData & operator = ( const MbSurfaceWorkingData & ); // \ru Присвоить значение. \en Assign a value. }; //------------------------------------------------------------------------------ // \ru Конструктор по умолчанию \en Default constructor // --- inline MbSurfaceWorkingData::MbSurfaceWorkingData() : uv0( UNDEFINED_DBL, UNDEFINED_DBL ) , uv ( UNDEFINED_DBL, UNDEFINED_DBL ) , ext( false ) { for ( size_t k = 0; k < sdt_CountDer; k++ ) ders[k].Init( UNDEFINED_DBL, UNDEFINED_DBL, UNDEFINED_DBL ); norm.Init( UNDEFINED_DBL, UNDEFINED_DBL, UNDEFINED_DBL ); } //------------------------------------------------------------------------------ // \ru Конструктор копирования. \en Copy-constructor. // --- inline MbSurfaceWorkingData::MbSurfaceWorkingData( const MbSurfaceWorkingData & init ) : uv0( init.uv0 ) , uv ( init.uv ) , ext( init.ext ) { for ( size_t k = 0; k < sdt_CountDer; k++ ) ders[k].Init( init.ders[k] ); norm.Init( init.norm ); } //------------------------------------------------------------------------------ // \ru Установить пустые значения. \en Set empty values. // --- inline void MbSurfaceWorkingData::Init() { ext = false; uv0.x = UNDEFINED_DBL; uv.x = UNDEFINED_DBL; for ( size_t k = 0; k < sdt_CountDer; k++ ) ders[k].x = UNDEFINED_DBL; norm.x = UNDEFINED_DBL; } //------------------------------------------------------------------------------ // \ru Установить значения. \en Set values. // --- inline void MbSurfaceWorkingData::Init( const MbSurfaceWorkingData & init ) { ext = init.ext; uv0.Init( init.uv0 ); uv.Init( init.uv ); for ( size_t k = 0; k < sdt_CountDer; k++ ) ders[k].Init( init.ders[k] ); norm.Init( init.norm ); } //------------------------------------------------------------------------------ // \ru Сдвинуть значения по вектору. \en Move values by vector. // --- inline void MbSurfaceWorkingData::Move( const MbVector3D & to ) { if ( ders[sdt_SurPoint].x != UNDEFINED_DBL ) ders[sdt_SurPoint].Add( to ); } //------------------------------------------------------------------------------ // \ru Установить точку. \en Set point. // --- inline void MbSurfaceWorkingData::SetPoint( double u0, double v0, bool ext0, double u, double v, const MbCartPoint3D & pnt ) { bool resetOther = true; if ( (ext == ext0) && (u0 == uv0.x) && (v0 == uv0.y) ) { ders[sdt_SurPoint].Init( pnt ); resetOther = false; } if ( resetOther ) { ext = ext0; uv0.Init( u0, v0 ); uv.Init( u, v ); for ( size_t i = 0; i < sdt_CountDer; i++ ) ders[i].x = UNDEFINED_DBL; norm.x = UNDEFINED_DBL; ders[sdt_SurPoint].Init( pnt.x, pnt.y, pnt.z ); } } //------------------------------------------------------------------------------ // \ru Получить точку. \en Get point. // --- inline bool MbSurfaceWorkingData::GetPoint( double u0, double v0, bool ext0, double & u, double & v, MbCartPoint3D & pnt ) const { if ( (ext == ext0) && (u0 == uv0.x) && (v0 == uv0.y) ) { if ( ders[sdt_SurPoint].x != UNDEFINED_DBL ) { u = uv.x; v = uv.y; pnt.Init( ders[sdt_SurPoint].x, ders[sdt_SurPoint].y, ders[sdt_SurPoint].z ); return true; } } return false; } //------------------------------------------------------------------------------ // \ru Установить производную. \en Set derivative. // --- inline bool MbSurfaceWorkingData::SetDerivative( double u0, double v0, bool ext0, double u, double v, size_t k, const MbVector3D & der ) { C3D_ASSERT( k < sdt_CountDer ); if ( k >= sdt_CountDer ) return false; bool resetOther = true; if ( (ext == ext0) && (u0 == uv0.x) && (v0 == uv0.y) ) { ders[k].Init( der ); resetOther = false; } if ( resetOther ) { ext = ext0; uv0.Init( u0, v0 ); uv.Init( u, v ); for ( size_t i = 0; i < sdt_CountDer; i++ ) ders[i].x = UNDEFINED_DBL; norm.x = UNDEFINED_DBL; ders[k].Init( der ); } return true; } //------------------------------------------------------------------------------ // \ru Получить производную. \en Get derivative. // --- inline bool MbSurfaceWorkingData::GetDerivative( double u0, double v0, bool ext0, double & u, double & v, size_t k, MbVector3D & der ) const { if ( (k < sdt_CountDer) && (ext == ext0) && (u0 == uv0.x) && (v0 == uv0.y) ) { if ( ders[k].x != UNDEFINED_DBL ) { u = uv.x; v = uv.y; der.Init( ders[k].x, ders[k].y, ders[k].z ); return true; } } return false; } //------------------------------------------------------------------------------ // \ru Установить исходный параметр. \en Set initial parameter. // --- inline void MbSurfaceWorkingData::_SetParams0( double u0, double v0, bool ext0 ) { uv0.x = u0; uv0.y = v0; ext = ext0; } //------------------------------------------------------------------------------ // \ru Установить модифицированный параметр. \en Set modified parameter. // --- inline void MbSurfaceWorkingData::_SetParams( double u, double v ) { uv.x = u; uv.y = v; } //------------------------------------------------------------------------------ // \ru Установить нормаль. \en Set normal. // --- inline void MbSurfaceWorkingData::_SetNormal( const MbVector3D & n ) { norm.Init( n ); } //------------------------------------------------------------------------------ // \ru Установить производную. \en Set derivative. // --- inline bool MbSurfaceWorkingData::_SetDerivative( size_t k, const MbVector3D & der ) { if ( k < sdt_CountDer ) { ders[k].Init( der ); return true; } return false; } //------------------------------------------------------------------------------ // \ru Получить данные. \en Get data. // --- inline bool MbSurfaceWorkingData::Explore( double u0, double v0, bool ext0, double & u, double & v, MbCartPoint3D & pnt, MbVector3D & uDer, MbVector3D & vDer, MbVector3D * uuDer, MbVector3D * vvDer, MbVector3D * uvDer, MbVector3D * nor ) const { bool res = false; // \\omega\Kernel\Models\Building\Konkurs_2012b\60114\кабина\бампер.c3d // if ( (ext == ext0) && (::fabs(u0 - uv0.x) < EXTENT_EQUAL) && (::fabs(v0 - uv0.y) < EXTENT_EQUAL) ) { if ( (ext == ext0) && (u0 == uv0.x) && (v0 == uv0.y) ) { if ( ders[sdt_SurPoint].x != UNDEFINED_DBL && ders[sdt_DeriveU].x != UNDEFINED_DBL && ders[sdt_DeriveV].x != UNDEFINED_DBL ) { bool resUU = false; bool resUV = false; bool resVV = false; if ( uuDer == nullptr ) resUU = true; else if ( ders[sdt_DeriveUU].x != UNDEFINED_DBL ) { uuDer->Init( ders[sdt_DeriveUU] ); resUU = true; } if ( uvDer == nullptr ) resUV = true; else if ( ders[sdt_DeriveUV].x != UNDEFINED_DBL ) { uvDer->Init( ders[sdt_DeriveUV] ); resUV = true; } if ( vvDer == nullptr ) resVV = true; else if ( ders[sdt_DeriveVV].x != UNDEFINED_DBL ) { vvDer->Init( ders[sdt_DeriveVV] ); resVV = true; } if ( resUU && resUV && resVV ) { if ( nor == nullptr ) res = true; else if ( norm.x != UNDEFINED_DBL ) { nor->Init( norm ); res = true; } if ( res ) { u = uv.x; v = uv.y; const MbVector3D & der0 = ders[sdt_SurPoint]; pnt.Init( der0.x, der0.y, der0.z ); uDer.Init( ders[sdt_DeriveU] ); vDer.Init( ders[sdt_DeriveV] ); } } } } return res; } //------------------------------------------------------------------------------ /** \brief \ru Дополнительные (сопутствующие) данные о поверхности. \en Additional (related) surface data. \~ \details \ru Дополнительные (сопутствующие) данные о поверхности. \en Additional (related) surface data. \~ \ingroup Data_Structures */ // --- class MATH_CLASS MbSurfaceContiguousData { private: MbeSurfacePoleType poleUMin; ///< \ru Флаг полюса на границе Umin. \en Pole flag on the border Umin. MbeSurfacePoleType poleUMax; ///< \ru Флаг полюса на границе Umax. \en Pole flag on the border Umax. MbeSurfacePoleType poleVMin; ///< \ru Флаг полюса на границе Vmin. \en Pole flag on the border Vmin. MbeSurfacePoleType poleVMax; ///< \ru Флаг полюса на границе Vmax. \en Pole flag on the border Vmax. MbRect1D uExtRange; ///< \ru Параметрический интервал U на продолженной поверхности. \en Parametric extended surface interval U. MbRect1D vExtRange; ///< \ru Параметрический интервал V на продолженной поверхности. \en Parametric extended surface interval V. ThreeStates isLineU; ///< \ru Флаг линейности вдоль параметра U. \en Flags of linearity along parameter U. ThreeStates isLineV; ///< \ru Флаг линейности вдоль параметра V. \en Flags of linearity along parameter V. ThreeStates isPlanar; ///< \ru Флаг планарности. \en Planarity flag. size_t uCount; ///< \ru Число разбиений по U. \en The number of partitions along parameter U. size_t vCount; ///< \ru Число разбиений по V. \en The number of partitions along parameter V. MbSurfaceTessellation tessellation; ///< \ru Разбивка поверхности. \en Surface tessellation. public: MbSurfaceContiguousData(); // \ru Конструктор по умолчанию \en Default constructor MbSurfaceContiguousData( const MbSurfaceContiguousData & other ); // \ru Конструктор копирования. \en Copy-constructor. void Reset (); // \ru Сбросить данные. \en Reset data. void ResetExceptBordersData(); // \ru Сбросить данные. \en Reset data. void Init ( const MbSurfaceContiguousData & other ); // \ru Установить данные. \en Set data. MbSurfaceContiguousData & operator = ( const MbSurfaceContiguousData & other ); // \ru Присвоить значение. \en Assign a value. public: MbeSurfacePoleType & PoleUMin () { return poleUMin; } // \ru Получить флаг полюса на границе Umin. \en Get the pole flag on the border Umin. MbeSurfacePoleType & PoleUMax () { return poleUMax; } // \ru Получить флаг полюса на границе Umax. \en Get the pole flag on the border Umax. MbeSurfacePoleType & PoleVMin () { return poleVMin; } // \ru Получить флаг полюса на границе Vmin. \en Get the pole flag on the border Vmin. MbeSurfacePoleType & PoleVMax () { return poleVMax; } // \ru Получить Флаг полюса на границе Vmax. \en Get the pole flag on the border Vmax. MbRect1D & URange () { return uExtRange; } // \ru Получить параметрический интервал U на продолженной поверхности. \en Get the parametric extended surface interval U. MbRect1D & VRange () { return vExtRange; } // \ru Получить параметрический интервал V на продолженной поверхности. \en Get the parametric extended surface interval V. ThreeStates & LineU () { return isLineU; } // \ru Получить флаг линейности вдоль параметра U. \en Get the flags of linearity along parameter U. ThreeStates & LineV () { return isLineV; } // \ru Получить флаг линейности вдоль параметра V. \en Get the flags of linearity along parameter V. ThreeStates & Planar () { return isPlanar; } // \ru Получить флаг планарности. \en Get the planarity flag. size_t & UCount () { return uCount; } // \ru Получить число разбиений по U. \en Get the number of partitions along parameter U. size_t & VCount () { return vCount; } // \ru Получить число разбиений по V. \en Get the number of partitions along parameter V. MbSurfaceTessellation & Tessellation() { return tessellation; } // \ru Получить разбивку поверхности. \en Get the surface tessellation. void ClearTessellation() { tessellation.Clear(); } // \ru Очистить разбивку. \en Clear tessellation. }; #endif // __SURF_TESSELLATION_H